diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc index a20acd8..d861806 100644 --- a/core/includes/ajax.inc +++ b/core/includes/ajax.inc @@ -516,7 +516,7 @@ function ajax_prepare_response($page_callback_result) { case MENU_SITE_OFFLINE: $commands[] = ajax_command_alert(filter_xss_admin(variable_get('maintenance_mode_message', - t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))))); + t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => config('system.site')->get('name')))))); break; } } diff --git a/core/includes/common.inc b/core/includes/common.inc index 19e0d59..5530f04 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2532,6 +2532,7 @@ function drupal_deliver_html_page($page_callback_result) { // Menu status constants are integers; page content is a string or array. if (is_int($page_callback_result)) { + $site_config = config('system.site'); // @todo: Break these up into separate functions? switch ($page_callback_result) { case MENU_NOT_FOUND: @@ -2548,7 +2549,7 @@ function drupal_deliver_html_page($page_callback_result) { $_GET['destination'] = current_path(); } - $path = drupal_get_normal_path(variable_get('site_404', '')); + $path = drupal_get_normal_path($site_config->get('page.404')); if ($path && $path != current_path()) { // Custom 404 handler. Set the active item in case there are tabs to // display, or other dependencies on the path. @@ -2577,7 +2578,7 @@ function drupal_deliver_html_page($page_callback_result) { $_GET['destination'] = current_path(); } - $path = drupal_get_normal_path(variable_get('site_403', '')); + $path = drupal_get_normal_path($site_config->get('page.403')); if ($path && $path != current_path()) { // Custom 403 handler. Set the active item in case there are tabs to // display or other dependencies on the path. @@ -2600,7 +2601,7 @@ function drupal_deliver_html_page($page_callback_result) { drupal_add_http_header('Status', '503 Service unavailable'); drupal_set_title(t('Site under maintenance')); print theme('maintenance_page', array('content' => filter_xss_admin(variable_get('maintenance_mode_message', - t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal'))))))); + t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => $site_config->get('name'))))))); break; } } diff --git a/core/includes/gettext.inc b/core/includes/gettext.inc index 4e3b221..ef9d25d 100644 --- a/core/includes/gettext.inc +++ b/core/includes/gettext.inc @@ -955,7 +955,7 @@ function _locale_export_po_generate($language = NULL, $strings = array(), $heade if (!isset($header)) { if (isset($language)) { - $header = '# ' . $language->name . ' translation of ' . variable_get('site_name', 'Drupal') . "\n"; + $header = '# ' . $language->name . ' translation of ' . config('system.site')->get('name') . "\n"; $header .= '# Generated by ' . $user->name . ' <' . $user->mail . ">\n"; $header .= "#\n"; $header .= "msgid \"\"\n"; diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index e62a7b5..36a35c0 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1896,8 +1896,11 @@ function install_configure_form_validate($form, &$form_state) { function install_configure_form_submit($form, &$form_state) { global $user; - variable_set('site_name', $form_state['values']['site_name']); - variable_set('site_mail', $form_state['values']['site_mail']); + config('system.site') + ->set('name', $form_state['values']['site_name']) + ->set('mail', $form_state['values']['site_mail']) + ->save(); + variable_set('date_default_timezone', $form_state['values']['date_default_timezone']); variable_set('site_default_country', $form_state['values']['site_default_country']); diff --git a/core/includes/mail.inc b/core/includes/mail.inc index f58a76e..c03fb0e 100644 --- a/core/includes/mail.inc +++ b/core/includes/mail.inc @@ -118,7 +118,8 @@ define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER * 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) { - $default_from = variable_get('site_mail', ini_get('sendmail_from')); + $site_mail = config('system.site')->get('mail'); + $default_from = (!empty($site_mail) ? $site_mail : ini_get('sendmail_from')); // Bundle up the variables into a structured array for altering. $message = array( diff --git a/core/includes/path.inc b/core/includes/path.inc index 0c7e4d4..62a58a6 100644 --- a/core/includes/path.inc +++ b/core/includes/path.inc @@ -22,7 +22,7 @@ function drupal_path_initialize() { // If on the front page, resolve to the front page path, including for calls // to current_path() while drupal_get_normal_path() is in progress. if (empty($path)) { - $path = variable_get('site_frontpage', 'user'); + $path = config('system.site')->get('page.front'); _current_path($path); } @@ -298,7 +298,7 @@ function drupal_is_front_page() { $is_front_page = &$drupal_static_fast['is_front_page']; if (!isset($is_front_page)) { - $is_front_page = (current_path() == variable_get('site_frontpage', 'user')); + $is_front_page = (current_path() == config('system.site')->get('page.front')); } return $is_front_page; @@ -329,7 +329,7 @@ function drupal_match_path($path, $patterns) { $replacements = array( '|', '.*', - '\1' . preg_quote(variable_get('site_frontpage', 'user'), '/') . '\2' + '\1' . preg_quote(config('system.site')->get('page.front'), '/') . '\2' ); $patterns_quoted = preg_quote($patterns, '/'); $regexps[$patterns] = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')$/'; diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 7d638f6..2466670 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -2530,17 +2530,18 @@ function template_preprocess_html(&$variables) { drupal_add_html_head_link(array('rel' => 'shortcut icon', 'href' => drupal_strip_dangerous_protocols($favicon), 'type' => $type)); } + $site_config = config('system.site'); // Construct page title. if (drupal_get_title()) { $head_title = array( 'title' => strip_tags(drupal_get_title()), - 'name' => check_plain(variable_get('site_name', 'Drupal')), + 'name' => check_plain($site_config->get('name')), ); } else { - $head_title = array('name' => check_plain(variable_get('site_name', 'Drupal'))); - if (variable_get('site_slogan', '')) { - $head_title['slogan'] = filter_xss_admin(variable_get('site_slogan', '')); + $head_title = array('name' => check_plain($site_config->get('name'))); + if ($site_config->get('slogan')) { + $head_title['slogan'] = filter_xss_admin($site_config->get('slogan')); } } $variables['head_title_array'] = $head_title; @@ -2574,6 +2575,7 @@ function template_preprocess_html(&$variables) { */ function template_preprocess_page(&$variables) { $language_interface = drupal_container()->get(LANGUAGE_TYPE_INTERFACE); + $site_config = config('system.site'); // Move some variables to the top level for themer convenience and template cleanliness. $variables['show_messages'] = $variables['page']['#show_messages']; @@ -2602,8 +2604,8 @@ function template_preprocess_page(&$variables) { $variables['main_menu'] = theme_get_setting('toggle_main_menu') ? menu_main_menu() : array(); $variables['secondary_menu'] = theme_get_setting('toggle_secondary_menu') ? menu_secondary_menu() : array(); $variables['action_links'] = menu_local_actions(); - $variables['site_name'] = (theme_get_setting('toggle_name') ? filter_xss_admin(variable_get('site_name', 'Drupal')) : ''); - $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? filter_xss_admin(variable_get('site_slogan', '')) : ''); + $variables['site_name'] = (theme_get_setting('toggle_name') ? filter_xss_admin($site_config->get('name')) : ''); + $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? filter_xss_admin($site_config->get('slogan')) : ''); $variables['tabs'] = menu_local_tabs(); if ($node = menu_get_object()) { @@ -2784,17 +2786,18 @@ function template_preprocess_maintenance_page(&$variables) { $variables['layout'] = ($variables['layout'] == 'first') ? 'both' : 'second'; } + $site_config = config('system.site'); // Construct page title if (drupal_get_title()) { $head_title = array( 'title' => strip_tags(drupal_get_title()), - 'name' => variable_get('site_name', 'Drupal'), + 'name' => $site_config->get('name'), ); } else { - $head_title = array('name' => variable_get('site_name', 'Drupal')); - if (variable_get('site_slogan', '')) { - $head_title['slogan'] = variable_get('site_slogan', ''); + $head_title = array('name' => $site_config->get('name')); + if ($site_config->get('slogan')) { + $head_title['slogan'] = $site_config->get('slogan'); } } @@ -2813,8 +2816,8 @@ function template_preprocess_maintenance_page(&$variables) { $variables['messages'] = $variables['show_messages'] ? theme('status_messages') : ''; $variables['main_menu'] = array(); $variables['secondary_menu'] = array(); - $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''); - $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? variable_get('site_slogan', '') : ''); + $variables['site_name'] = (theme_get_setting('toggle_name') ? $site_config->get('name') : ''); + $variables['site_slogan'] = (theme_get_setting('toggle_slogan') ? $site_config->get('slogan') : ''); $variables['tabs'] = ''; $variables['title'] = drupal_get_title(); diff --git a/core/modules/aggregator/aggregator.pages.inc b/core/modules/aggregator/aggregator.pages.inc index 7f82077..0c82b05 100644 --- a/core/modules/aggregator/aggregator.pages.inc +++ b/core/modules/aggregator/aggregator.pages.inc @@ -11,7 +11,7 @@ * @see aggregator_menu() */ function aggregator_page_last() { - drupal_add_feed('aggregator/rss', variable_get('site_name', 'Drupal') . ' ' . t('aggregator')); + drupal_add_feed('aggregator/rss', config('system.site')->get('name') . ' ' . t('aggregator')); $items = aggregator_load_feed_items('sum'); @@ -61,7 +61,7 @@ function aggregator_page_source_form($form, $form_state, $feed) { * @ingroup forms */ function aggregator_page_category($category) { - drupal_add_feed('aggregator/rss/' . $category['cid'], variable_get('site_name', 'Drupal') . ' ' . t('aggregator - @title', array('@title' => $category['title']))); + drupal_add_feed('aggregator/rss/' . $category['cid'], config('system.site')->get('name') . ' ' . t('aggregator - @title', array('@title' => $category['title']))); // It is safe to include the cid in the query because it's loaded from the // database by aggregator_category_load(). @@ -452,7 +452,7 @@ function theme_aggregator_page_rss($variables) { $items .= format_rss_item($feed->ftitle . ': ' . $feed->title, $feed->link, $feed->description, array('pubDate' => date('r', $feed->timestamp))); } - $site_name = variable_get('site_name', 'Drupal'); + $site_name = config('system.site')->get('name'); $url = url((isset($category) ? 'aggregator/categories/' . $category->cid : 'aggregator'), array('absolute' => TRUE)); $description = isset($category) ? t('@site_name - aggregated feeds in category @title', array('@site_name' => $site_name, '@title' => $category->title)) : t('@site_name - aggregated feeds', array('@site_name' => $site_name)); @@ -504,7 +504,7 @@ function theme_aggregator_page_opml($variables) { $output = "\n"; $output .= "\n"; $output .= "\n"; - $output .= '' . check_plain(variable_get('site_name', 'Drupal')) . "\n"; + $output .= '' . check_plain(config('system.site')->get('name')) . "\n"; $output .= '' . gmdate(DATE_RFC2822, REQUEST_TIME) . "\n"; $output .= "\n"; $output .= "\n"; diff --git a/core/modules/block/block.install b/core/modules/block/block.install index 632e106..7544c33 100644 --- a/core/modules/block/block.install +++ b/core/modules/block/block.install @@ -224,6 +224,8 @@ function block_install() { /** * Block cache is always enabled in 8.x. + * + * @ingroup config_upgrade */ function block_update_8000() { variable_del('block_cache'); diff --git a/core/modules/block/block.test b/core/modules/block/block.test index e6b2e42..9eed381 100644 --- a/core/modules/block/block.test +++ b/core/modules/block/block.test @@ -166,7 +166,7 @@ class BlockTestCase extends WebTestBase { function testBlockVisibility() { // Enable Node module and change the front page path to 'node'. module_enable(array('node')); - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); $block = array(); diff --git a/core/modules/contact/contact.install b/core/modules/contact/contact.install index 7ddea45..5956740 100644 --- a/core/modules/contact/contact.install +++ b/core/modules/contact/contact.install @@ -68,11 +68,15 @@ function contact_schema() { * Implements hook_install(). */ function contact_install() { + $site_mail = config('system.site')->get('mail'); + if (empty($site_mail)) { + $site_mail = ini_get('sendmail_from'); + } // Insert a default contact category. db_insert('contact') ->fields(array( 'category' => 'Website feedback', - 'recipients' => variable_get('site_mail', ini_get('sendmail_from')), + 'recipients' => $site_mail, 'selected' => 1, 'reply' => '', )) diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index 48c12d9..dc43fc9 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -170,7 +170,7 @@ function contact_load($cid) { function contact_mail($key, &$message, $params) { $language = $message['language']; $variables = array( - '!site-name' => variable_get('site_name', 'Drupal'), + '!site-name' => config('system.site')->get('name'), '!subject' => $params['subject'], '!category' => isset($params['category']['category']) ? $params['category']['category'] : '', '!form-url' => url(current_path(), array('absolute' => TRUE, 'language' => $language)), diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index 94d8a03..23fad42 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -1277,7 +1277,7 @@ function _filter_html_tips($filter, $format, $long = FALSE) { $output .= '

' . t('This site allows HTML content. While learning all of HTML may feel intimidating, learning how to use a very small number of the most basic HTML "tags" is very easy. This table provides examples for each tag that is enabled on this site.') . '

'; $output .= '

' . t('For more information see W3C\'s HTML Specifications or use your favorite search engine to find other sites that explain HTML.', array('@html-specifications' => 'http://www.w3.org/TR/html/')) . '

'; $tips = array( - 'a' => array(t('Anchors are used to make links to other pages.'), '' . check_plain(variable_get('site_name', 'Drupal')) . ''), + 'a' => array(t('Anchors are used to make links to other pages.'), '' . check_plain(config('system.site')->get('name')) . ''), 'br' => array(t('By default line break tags are automatically added, so use this tag to add additional ones. Use of this tag is different because it is not used with an open/close pair like all the others. Use the extra " /" inside the tag to maintain XHTML 1.0 compatibility'), t('Text with
line break')), 'p' => array(t('By default paragraph tags are automatically added, so use this tag to add additional ones.'), '

' . t('Paragraph one.') . '

' . t('Paragraph two.') . '

'), 'strong' => array(t('Strong', array(), array('context' => 'Font weight')), '' . t('Strong', array(), array('context' => 'Font weight')) . ''), diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index b29bdee..ac03baa 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -157,6 +157,8 @@ function locale_update_8000() { /** * Language type 'language' renamed to 'language_interface'. + * + * @ingroup config_upgrade */ function locale_update_8001() { // Only change language_types if we had this setting saved. Keep order @@ -242,6 +244,8 @@ function locale_update_8002() { /** * Converts language domains to new format. + * + * @ingroup config_upgrade */ function locale_update_8003() { $message = ''; @@ -274,6 +278,8 @@ function locale_update_8003() { /** * Rename language providers to language negotiation methods. + * + * @ingroup config_upgrade */ function locale_update_8004() { $types = variable_get('language_types', NULL); @@ -437,6 +443,8 @@ function locale_update_8006() { /** * Convert language_negotiation_* variables to use the new callbacks. + * + * @ingroup config_upgrade */ function locale_update_8007() { $variable_names = array( @@ -510,6 +518,8 @@ function locale_update_8007() { /** * Rename the option variables of the locale language negotiation. + * + * @ingroup config_upgrade */ function locale_update_8008() { $variable_name_map = array( diff --git a/core/modules/locale/locale.test b/core/modules/locale/locale.test index 5e252bf..3ad90e4 100644 --- a/core/modules/locale/locale.test +++ b/core/modules/locale/locale.test @@ -1642,7 +1642,7 @@ class LocalePathFunctionalTest extends WebTestBase { parent::setUp(array('node', 'locale', 'path')); $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); } /** diff --git a/core/modules/node/node.install b/core/modules/node/node.install index ee89059..3ad8dad 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -475,7 +475,6 @@ function node_uninstall() { variable_del('node_admin_theme'); variable_del('node_cron_last'); variable_del('node_recent_block_count'); - variable_del('default_nodes_main'); } /** @@ -519,6 +518,8 @@ function _update_7000_node_get_types() { * old implicit default is still the default. * * @see http://drupal.org/node/375397 + * + * @ingroup config_upgrade */ function node_update_8000() { $front_page = variable_get('site_frontpage'); @@ -531,6 +532,8 @@ function node_update_8000() { * Rename node type language variable names. * * @see http://drupal.org/node/540294 + * + * @ingroup config_upgrade */ function node_update_8001() { $types = db_query('SELECT type FROM {node_type}')->fetchCol(); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 3c3881d..05e2335 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -2429,7 +2429,7 @@ function node_feed($nids = FALSE, $channel = array()) { $channel_defaults = array( 'version' => '2.0', - 'title' => variable_get('site_name', 'Drupal'), + 'title' => config('system.site')->get('name'), 'link' => $base_url, 'description' => config('system.rss-publishing')->get('feed_description'), 'language' => $language_content->langcode @@ -2481,6 +2481,7 @@ function node_view_multiple($nodes, $view_mode = 'teaser', $weight = 0, $langcod * @see node_menu() */ function node_page_default() { + $site_config = config('system.site'); $select = db_select('node', 'n') ->fields('n', array('nid', 'sticky', 'created')) ->condition('promote', 1) @@ -2488,7 +2489,7 @@ function node_page_default() { ->orderBy('sticky', 'DESC') ->orderBy('created', 'DESC') ->extend('PagerDefault') - ->limit(variable_get('default_nodes_main', 10)) + ->limit($site_config->get('default_nodes_main')) ->addTag('node_access'); $nids = $select->execute()->fetchCol(); @@ -2498,7 +2499,7 @@ function node_page_default() { $build = node_view_multiple($nodes); // 'rss.xml' is a path, not a file, registered in node_menu(). - drupal_add_feed('rss.xml', variable_get('site_name', 'Drupal') . ' ' . t('RSS')); + drupal_add_feed('rss.xml', $site_config->get('name') . ' ' . t('RSS')); $build['pager'] = array( '#theme' => 'pager', '#weight' => 5, @@ -2506,7 +2507,7 @@ function node_page_default() { drupal_set_title(''); } else { - drupal_set_title(t('Welcome to @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), PASS_THROUGH); + drupal_set_title(t('Welcome to @site-name', array('@site-name' => $site_config->get('name'))), PASS_THROUGH); $default_message = '

' . t('No front page content has been created yet.') . '

'; diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module index 02c0883..2be68e6 100644 --- a/core/modules/overlay/overlay.module +++ b/core/modules/overlay/overlay.module @@ -635,7 +635,7 @@ function overlay_overlay_parent_initialize() { // Let the client side know which paths are administrative. $paths = path_get_admin_paths(); foreach ($paths as &$type) { - $type = str_replace('', variable_get('site_frontpage', 'user'), $type); + $type = str_replace('', config('system.site')->get('page.front'), $type); } drupal_add_js(array('overlay' => array('paths' => $paths)), 'setting'); $path_prefixes = array(); diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index eb7c5a3..065f156 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -752,7 +752,7 @@ abstract class WebTestBase extends TestBase { // Restore necessary variables. variable_set('install_task', 'done'); - variable_set('site_mail', 'simpletest@example.com'); + config('system.site')->set('mail', 'simpletest@example.com')->save(); variable_set('date_default_timezone', date_default_timezone_get()); // Set up English language. diff --git a/core/modules/simpletest/simpletest.test b/core/modules/simpletest/simpletest.test index cc4e026..19fb031 100644 --- a/core/modules/simpletest/simpletest.test +++ b/core/modules/simpletest/simpletest.test @@ -49,7 +49,7 @@ class SimpleTestFunctionalTest extends WebTestBase { if (!$this->inCURL()) { $this->drupalGet('node'); $this->assertTrue($this->drupalGetHeader('Date'), t('An HTTP header was received.')); - $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), t('Site title matches.')); + $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => config('system.site')->get('name'))), t('Site title matches.')); $this->assertNoTitle('Foo', t('Site title does not match.')); // Make sure that we are locked out of the installer when prefixing // using the user-agent header. This is an important security check. diff --git a/core/modules/system/config/system.site.yml b/core/modules/system/config/system.site.yml new file mode 100644 index 0000000..886ef5f --- /dev/null +++ b/core/modules/system/config/system.site.yml @@ -0,0 +1,8 @@ +name: Drupal +mail: '' +slogan: '' +default_nodes_main: '10' +page: + front: user + 403: '' + 404: '' diff --git a/core/modules/system/language.api.php b/core/modules/system/language.api.php index 9f28619..e6dbd3d 100644 --- a/core/modules/system/language.api.php +++ b/core/modules/system/language.api.php @@ -28,11 +28,11 @@ function hook_language_init() { switch (drupal_container()->get(LANGUAGE_TYPE_INTERFACE)->langcode) { case 'it': - $conf['site_name'] = 'Il mio sito Drupal'; + $conf['system.site']['name'] = 'Il mio sito Drupal'; break; case 'fr': - $conf['site_name'] = 'Mon site Drupal'; + $conf['system.site']['name'] = 'Mon site Drupal'; break; } } diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index f3e2012..0c785b3 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -1462,6 +1462,12 @@ function system_ip_blocking_delete_submit($form, &$form_state) { * @see system_settings_form() */ function system_site_information_settings() { + $site_config = config('system.site'); + $site_mail = $site_config->get('mail'); + if (empty($site_mail)) { + $site_mail = ini_get('sendmail_from'); + } + $form['site_information'] = array( '#type' => 'fieldset', '#title' => t('Site details'), @@ -1469,19 +1475,19 @@ function system_site_information_settings() { $form['site_information']['site_name'] = array( '#type' => 'textfield', '#title' => t('Site name'), - '#default_value' => variable_get('site_name', 'Drupal'), + '#default_value' => $site_config->get('name'), '#required' => TRUE ); $form['site_information']['site_slogan'] = array( '#type' => 'textfield', '#title' => t('Slogan'), - '#default_value' => variable_get('site_slogan', ''), + '#default_value' => $site_config->get('slogan'), '#description' => t("How this is used depends on your site's theme."), ); $form['site_information']['site_mail'] = array( '#type' => 'email', '#title' => t('E-mail address'), - '#default_value' => variable_get('site_mail', ini_get('sendmail_from')), + '#default_value' => $site_mail, '#description' => t("The From address in automated e-mails sent during registration and new password requests, and other notifications. (Use an address ending in your site's domain to help prevent this e-mail being flagged as spam.)"), '#required' => TRUE, ); @@ -1492,17 +1498,17 @@ function system_site_information_settings() { $form['front_page']['site_frontpage'] = array( '#type' => 'textfield', '#title' => t('Default front page'), - '#default_value' => (variable_get('site_frontpage') != 'user' ? drupal_get_path_alias(variable_get('site_frontpage', 'user')) : ''), + '#default_value' => ($site_config->get('page.front') != 'user' ? drupal_get_path_alias($site_config->get('page.front')) : ''), '#size' => 40, '#description' => t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default content feed.'), '#field_prefix' => url(NULL, array('absolute' => TRUE)), ); $form['front_page']['default_nodes_main'] = array( '#type' => 'select', '#title' => t('Number of posts on front page'), - '#default_value' => variable_get('default_nodes_main', 10), + '#default_value' => $site_config->get('default_nodes_main'), '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)), '#description' => t('The maximum number of posts displayed on overview pages such as the front page.'), - '#access' => (variable_get('site_frontpage') == 'node'), + '#access' => ($site_config->get('page.front') == 'node'), ); $form['error_page'] = array( '#type' => 'fieldset', @@ -1511,7 +1517,7 @@ function system_site_information_settings() { $form['error_page']['site_403'] = array( '#type' => 'textfield', '#title' => t('Default 403 (access denied) page'), - '#default_value' => variable_get('site_403', ''), + '#default_value' => $site_config->get('page.403'), '#size' => 40, '#description' => t('This page is displayed when the requested document is denied to the current user. Leave blank to display a generic "access denied" page.'), '#field_prefix' => url(NULL, array('absolute' => TRUE)), @@ -1519,7 +1525,7 @@ function system_site_information_settings() { $form['error_page']['site_404'] = array( '#type' => 'textfield', '#title' => t('Default 404 (not found) page'), - '#default_value' => variable_get('site_404', ''), + '#default_value' => $site_config->get('page.404'), '#size' => 40, '#description' => t('This page is displayed when no other content matches the requested document. Leave blank to display a generic "page not found" page.'), '#field_prefix' => url(NULL, array('absolute' => TRUE)), @@ -1527,6 +1533,8 @@ function system_site_information_settings() { $form['#validate'][] = 'system_site_information_settings_validate'; + // @todo Replace with configuration system settings form. + $form['#submit'][] = 'system_site_information_settings_submit'; return system_settings_form($form); } @@ -1565,6 +1573,21 @@ function system_site_information_settings_validate($form, &$form_state) { } /** + * Form submission handler for system_site_information_settings(). + */ +function system_site_information_settings_submit($form, &$form_state) { + config('system.site') + ->set('name', $form_state['values']['site_name']) + ->set('mail', $form_state['values']['site_mail']) + ->set('slogan', $form_state['values']['site_slogan']) + ->set('default_nodes_main', $form_state['values']['default_nodes_main']) + ->set('page.front', $form_state['values']['site_frontpage']) + ->set('page.403', $form_state['values']['site_403']) + ->set('page.404', $form_state['values']['site_404']) + ->save(); +} + +/** * Form builder; Cron form. * * @see system_settings_form() @@ -2235,7 +2258,7 @@ function system_site_maintenance_mode() { $form['maintenance_mode_message'] = array( '#type' => 'textarea', '#title' => t('Message to display when in maintenance mode'), - '#default_value' => variable_get('maintenance_mode_message', t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))), + '#default_value' => variable_get('maintenance_mode_message', t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => config('system.site')->get('name')))), ); return system_settings_form($form); diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index 2fb21c7..3a01bba 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -1525,7 +1525,7 @@ function hook_mail_alter(&$message) { $message['send'] = FALSE; return; } - $message['body'][] = "--\nMail sent out from " . variable_get('site_name', t('Drupal')); + $message['body'][] = "--\nMail sent out from " . config('system.site')->get('name'); } } @@ -1990,7 +1990,7 @@ function hook_watchdog(array $log_entry) { $to = 'someone@example.com'; $params = array(); $params['subject'] = t('[@site_name] @severity_desc: Alert from your web site', array( - '@site_name' => variable_get('site_name', 'Drupal'), + '@site_name' => config('system.site')->get('name'), '@severity_desc' => $severity_list[$log_entry['severity']], )); @@ -2056,7 +2056,7 @@ function hook_mail($key, &$message, $params) { $account = $params['account']; $context = $params['context']; $variables = array( - '%site_name' => variable_get('site_name', 'Drupal'), + '%site_name' => config('system.site')->get('name'), '%username' => user_format_name($account), ); if ($context['hook'] == 'taxonomy') { diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 199f8c0..d21478b 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1699,6 +1699,17 @@ function system_update_last_removed() { } /** + * @defgroup config_upgrade Configuration system upgrade functions + * @{ + * Module update functions that + * - update variables prior to configuration system conversions + * - convert variables to the new configuration system + * - update configuration system values after conversion + * + * @} End of "defgroup config_upgrade". + */ + +/** * @defgroup updates-7.x-to-8.x Updates from 7.x to 8.x * @{ * Update functions from 7.x to 8.x. @@ -1875,19 +1886,40 @@ function system_update_8008() { /** * Moves cron system settings from variable to config. + * + * @ingroup config_upgrade */ function system_update_8009() { update_variables_to_config('system.cron'); } /** - * Moves system settings from variable to config. + * Moves RSS system settings from variable to config. + * + * @ingroup config_upgrade */ function system_update_8010() { update_variables_to_config('system.rss-publishing'); } /** + * Moves site system settings from variable to config. + * + * @ingroup config_upgrade + */ +function system_update_8011() { + update_variables_to_config('system.site', array( + 'name' => 'site_name', + 'mail' => 'site_mail', + 'slogan' => 'site_slogan', + 'default_nodes_main' => 'default_nodes_main', + 'page.front' => 'site_frontpage', + 'page.403' => 'site_403', + 'page.404' => 'site_404', + )); +} + +/** * @} End of "defgroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/system/system.test b/core/modules/system/system.test index 40f590e..1550900 100644 --- a/core/modules/system/system.test +++ b/core/modules/system/system.test @@ -1052,7 +1052,7 @@ class AccessDeniedTestCase extends WebTestBase { // Log back in, set the custom 403 page to /user and remove the block $this->drupalLogin($this->admin_user); - variable_set('site_403', 'user'); + config('system.site')->set('page.403', 'user')->save(); $this->drupalPost('admin/structure/block', array('blocks[user_login][region]' => '-1'), t('Save blocks')); // Check that we can log in from the 403 page. @@ -1123,7 +1123,7 @@ class SiteMaintenanceTestCase extends WebTestBase { parent::setUp(array('node')); // Configure 'node' as front page. - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); // Create a user allowed to access site in maintenance mode. $this->user = $this->drupalCreateUser(array('access site in maintenance mode')); @@ -1144,7 +1144,7 @@ class SiteMaintenanceTestCase extends WebTestBase { $admin_message = t('Operating in maintenance mode. Go online.', array('@url' => url('admin/config/development/maintenance'))); $user_message = t('Operating in maintenance mode.'); - $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal'))); + $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => config('system.site')->get('name'))); $this->drupalGet(''); $this->assertRaw($admin_message, t('Found the site maintenance mode message.')); @@ -1533,7 +1533,7 @@ class FrontPageTestCase extends WebTestBase { $this->node_path = "node/" . $this->drupalCreateNode(array('promote' => 1))->nid; // Configure 'node' as front page. - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); // Enable front page logging in system_test.module. variable_set('front_page_output', 1); } @@ -2035,13 +2035,15 @@ class TokenReplaceTestCase extends WebTestBase { ); // Set a few site variables. - variable_set('site_name', 'Drupal'); - variable_set('site_slogan', 'Slogan'); + config('system.site') + ->set('name', 'Drupal') + ->set('slogan', 'Slogan') + ->save(); // Generate and test sanitized tokens. $tests = array(); - $tests['[site:name]'] = check_plain(variable_get('site_name', 'Drupal')); - $tests['[site:slogan]'] = check_plain(variable_get('site_slogan', '')); + $tests['[site:name]'] = check_plain(config('system.site')->get('name')); + $tests['[site:slogan]'] = check_plain(config('system.site')->get('slogan')); $tests['[site:mail]'] = 'simpletest@example.com'; $tests['[site:url]'] = url('', $url_options); $tests['[site:url-brief]'] = preg_replace(array('!^https?://!', '!/$!'), '', url('', $url_options)); @@ -2056,8 +2058,8 @@ class TokenReplaceTestCase extends WebTestBase { } // Generate and test unsanitized tokens. - $tests['[site:name]'] = variable_get('site_name', 'Drupal'); - $tests['[site:slogan]'] = variable_get('site_slogan', ''); + $tests['[site:name]'] = config('system.site')->get('name'); + $tests['[site:slogan]'] = config('system.site')->get('slogan'); foreach ($tests as $input => $expected) { $output = token_replace($input, array(), array('language' => $language_interface, 'sanitize' => FALSE)); diff --git a/core/modules/system/system.tokens.inc b/core/modules/system/system.tokens.inc index 2492890..d3df60e 100644 --- a/core/modules/system/system.tokens.inc +++ b/core/modules/system/system.tokens.inc @@ -145,17 +145,17 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a foreach ($tokens as $name => $original) { switch ($name) { case 'name': - $site_name = variable_get('site_name', 'Drupal'); + $site_name = config('system.site')->get('name'); $replacements[$original] = $sanitize ? check_plain($site_name) : $site_name; break; case 'slogan': - $slogan = variable_get('site_slogan', ''); + $slogan = config('system.site')->get('slogan'); $replacements[$original] = $sanitize ? check_plain($slogan) : $slogan; break; case 'mail': - $replacements[$original] = variable_get('site_mail', ''); + $replacements[$original] = config('system.site')->get('mail'); break; case 'url': diff --git a/core/modules/system/tests/bootstrap.test b/core/modules/system/tests/bootstrap.test index 098e12e..f219209 100644 --- a/core/modules/system/tests/bootstrap.test +++ b/core/modules/system/tests/bootstrap.test @@ -114,8 +114,10 @@ class BootstrapPageCacheTestCase extends WebTestBase { function setUp() { parent::setUp(array('node', 'system_test')); - variable_set('site_name', 'Drupal'); - variable_set('site_frontpage', 'node'); + config('system.site') + ->set('name', 'Drupal') + ->set('page.front', 'node') + ->save(); } /** @@ -229,7 +231,7 @@ class BootstrapPageCacheTestCase extends WebTestBase { $this->drupalGet(''); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', t('Page was cached.')); $this->assertFalse($this->drupalGetHeader('Content-Encoding'), t('A Content-Encoding header was not sent.')); - $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), t('Site title matches.')); + $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => config('system.site')->get('name'))), t('Site title matches.')); $this->assertRaw('', t('Page was not compressed.')); } } diff --git a/core/modules/system/tests/common.test b/core/modules/system/tests/common.test index b50daad..c61e033 100644 --- a/core/modules/system/tests/common.test +++ b/core/modules/system/tests/common.test @@ -887,7 +887,7 @@ class CommonDrupalHTTPRequestTestCase extends WebTestBase { $result = drupal_http_request(url('node', array('absolute' => TRUE))); $this->assertEqual($result->code, 200, t('Fetched page successfully.')); $this->drupalSetContent($result->data); - $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => variable_get('site_name', 'Drupal'))), t('Site title matches.')); + $this->assertTitle(t('Welcome to @site-name | @site-name', array('@site-name' => config('system.site')->get('name'))), t('Site title matches.')); // Test that code and status message is returned. $result = drupal_http_request(url('pagedoesnotexist', array('absolute' => TRUE))); diff --git a/core/modules/system/tests/menu.test b/core/modules/system/tests/menu.test index dbd94a1..c006ef1 100644 --- a/core/modules/system/tests/menu.test +++ b/core/modules/system/tests/menu.test @@ -248,7 +248,7 @@ class MenuRouterTestCase extends WebTestBase { function testMaintenanceModeLoginPaths() { variable_set('maintenance_mode', TRUE); - $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal'))); + $offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => config('system.site')->get('name'))); $this->drupalGet('node'); $this->assertText($offline_message); $this->drupalGet('menu_login_callback'); @@ -1636,8 +1636,10 @@ class MenuTrailTestCase extends MenuWebTestCase { */ function testCustom403And404Pages() { // Set the custom 403 and 404 pages we will use. - variable_set('site_403', 'menu-test/custom-403-page'); - variable_set('site_404', 'menu-test/custom-404-page'); + config('system.site') + ->set('page.403', 'menu-test/custom-403-page') + ->set('page.404', 'menu-test/custom-404-page') + ->save(); // Define the paths we'll visit to trigger 403 and 404 responses during // this test, and the expected active trail for each case. diff --git a/core/modules/system/tests/path.test b/core/modules/system/tests/path.test index 271cd91..982550b 100644 --- a/core/modules/system/tests/path.test +++ b/core/modules/system/tests/path.test @@ -29,7 +29,7 @@ class DrupalMatchPathTestCase extends WebTestBase { // Set up a random site front page to test the '' placeholder. $this->front = $this->randomName(); - variable_set('site_frontpage', $this->front); + config('system.site')->set('page.front', $this->front)->save(); // Refresh our static variables from the database. $this->refreshVariables(); } diff --git a/core/modules/system/tests/theme.test b/core/modules/system/tests/theme.test index d7c6fb2..c2e3009 100644 --- a/core/modules/system/tests/theme.test +++ b/core/modules/system/tests/theme.test @@ -31,7 +31,7 @@ class ThemeUnitTest extends WebTestBase { function testThemeSuggestions() { // Set the front page as something random otherwise the CLI // test runner fails. - variable_set('site_frontpage', 'nobody-home'); + config('system.site')->set('page.front', 'nobody-home')->save(); $args = array('node', '1', 'edit'); $suggestions = theme_get_suggestions($args, 'page'); $this->assertEqual($suggestions, array('page__node', 'page__node__%', 'page__node__1', 'page__node__edit'), t('Found expected node edit page suggestions')); @@ -75,7 +75,7 @@ class ThemeUnitTest extends WebTestBase { $original_path = _current_path(); // Set the current path to node because theme_get_suggestions() will query // it to see if we are on the front page. - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); _current_path('node'); $suggestions = theme_get_suggestions(array('node'), 'page'); // Set it back to not annoy the batch runner. @@ -320,7 +320,7 @@ class ThemeFunctionsTestCase extends WebTestBase { // Required to verify the "active" class in expected links below, and // because the current path is different when running tests manually via // simpletest.module ('batch') and via the testing framework (''). - _current_path(variable_get('site_frontpage', 'user')); + _current_path(config('system.site')->get('page.front')); // Verify that a list of links is properly rendered. $variables = array(); diff --git a/core/modules/system/tests/upgrade/upgrade.test b/core/modules/system/tests/upgrade/upgrade.test index 2f942fa..429bddb 100644 --- a/core/modules/system/tests/upgrade/upgrade.test +++ b/core/modules/system/tests/upgrade/upgrade.test @@ -128,6 +128,7 @@ abstract class UpgradePathTestCase extends WebTestBase { $this->prepareD8Session(); // Restore necessary variables. + // @todo Convert into config('system.site')->set('mail')? $this->variable_set('site_mail', 'simpletest@example.com'); drupal_set_time_limit($this->timeLimit); @@ -142,6 +143,8 @@ abstract class UpgradePathTestCase extends WebTestBase { * @param $value * The value to set. This can be any PHP data type; these functions take care * of serialization as necessary. + * + * @todo Update for D8 configuration system. */ protected function variable_set($name, $value) { db_delete('variable') diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc index c84a6bd..33c06fe 100644 --- a/core/modules/taxonomy/taxonomy.pages.inc +++ b/core/modules/taxonomy/taxonomy.pages.inc @@ -42,7 +42,7 @@ function taxonomy_term_page(Term $term) { 'term' => taxonomy_term_view($term, 'full'), ); - if ($nids = taxonomy_select_nodes($term->tid, TRUE, variable_get('default_nodes_main', 10))) { + if ($nids = taxonomy_select_nodes($term->tid, TRUE, config('system.site')->get('default_nodes_main'))) { $nodes = node_load_multiple($nids); $build += node_view_multiple($nodes); $build['pager'] = array( @@ -68,7 +68,7 @@ function taxonomy_term_page(Term $term) { */ function taxonomy_term_feed(Term $term) { $channel['link'] = url('taxonomy/term/' . $term->tid, array('absolute' => TRUE)); - $channel['title'] = variable_get('site_name', 'Drupal') . ' - ' . $term->name; + $channel['title'] = config('system.site')->get('name') . ' - ' . $term->name; // Only display the description if we have a single term, to avoid clutter and confusion. // HTML will be removed from feed description. $channel['description'] = check_markup($term->description, $term->format, '', TRUE); diff --git a/core/modules/update/update.module b/core/modules/update/update.module index 4b3eab2..c3a95f9 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -500,7 +500,7 @@ function _update_get_cached_available_releases() { function update_mail($key, &$message, $params) { $language = $message['language']; $langcode = $language->langcode; - $message['subject'] .= t('New release(s) available for !site_name', array('!site_name' => variable_get('site_name', 'Drupal')), array('langcode' => $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); } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index cfde270..5e9f4cc 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1876,7 +1876,7 @@ function user_login($form, &$form_state) { ), ); - $form['name']['#description'] = t('Enter your @s username.', array('@s' => variable_get('site_name', 'Drupal'))); + $form['name']['#description'] = t('Enter your @s username.', array('@s' => config('system.site')->get('name'))); $form['pass'] = array('#type' => 'password', '#title' => t('Password'), '#description' => t('Enter the password that accompanies your username.'), @@ -3337,7 +3337,11 @@ function _user_mail_notify($op, $account, $language = NULL) { if ($op == 'register_pending_approval') { // If a user registered requiring admin approval, notify the admin, too. // We use the site default language for this. - drupal_mail('user', 'register_pending_approval_admin', variable_get('site_mail', ini_get('sendmail_from')), language_default(), $params); + $site_mail = config('system.site')->get('mail'); + if (empty($site_mail)) { + $site_mail = ini_get('sendmail_from'); + } + drupal_mail('user', 'register_pending_approval_admin', $site_mail, language_default(), $params); } } return empty($mail) ? NULL : $mail['result']; diff --git a/core/themes/bartik/template.php b/core/themes/bartik/template.php index 7db1a31..eaeb38d 100644 --- a/core/themes/bartik/template.php +++ b/core/themes/bartik/template.php @@ -43,6 +43,7 @@ function bartik_process_html(&$variables) { * Implements hook_process_HOOK() for page.tpl.php. */ function bartik_process_page(&$variables) { + $site_config = config('system.site'); // Hook into color.module. if (module_exists('color')) { _color_page_alter($variables); @@ -53,11 +54,11 @@ function bartik_process_page(&$variables) { $variables['hide_site_slogan'] = theme_get_setting('toggle_slogan') ? FALSE : TRUE; if ($variables['hide_site_name']) { // If toggle_name is FALSE, the site_name will be empty, so we rebuild it. - $variables['site_name'] = filter_xss_admin(variable_get('site_name', 'Drupal')); + $variables['site_name'] = filter_xss_admin($site_config->get('name')); } if ($variables['hide_site_slogan']) { // If toggle_site_slogan is FALSE, the site_slogan will be empty, so we rebuild it. - $variables['site_slogan'] = filter_xss_admin(variable_get('site_slogan', '')); + $variables['site_slogan'] = filter_xss_admin($site_config->get('slogan')); } // Since the title and the shortcut link are both block level elements, // positioning them next to each other is much simpler with a wrapper div. @@ -94,17 +95,18 @@ function bartik_preprocess_maintenance_page(&$variables) { * Implements hook_process_HOOK() for maintenance-page.tpl.php. */ function bartik_process_maintenance_page(&$variables) { + $site_config = config('system.site'); // Always print the site name and slogan, but if they are toggled off, we'll // just hide them visually. $variables['hide_site_name'] = theme_get_setting('toggle_name') ? FALSE : TRUE; $variables['hide_site_slogan'] = theme_get_setting('toggle_slogan') ? FALSE : TRUE; if ($variables['hide_site_name']) { // If toggle_name is FALSE, the site_name will be empty, so we rebuild it. - $variables['site_name'] = filter_xss_admin(variable_get('site_name', 'Drupal')); + $variables['site_name'] = filter_xss_admin($site_config->get('name')); } if ($variables['hide_site_slogan']) { // If toggle_site_slogan is FALSE, the site_slogan will be empty, so we rebuild it. - $variables['site_slogan'] = filter_xss_admin(variable_get('site_slogan', '')); + $variables['site_slogan'] = filter_xss_admin($site_config->get('slogan')); } } diff --git a/profiles/minimal/minimal.install b/profiles/minimal/minimal.install index e02ffcc..2f9c9b8 100644 --- a/profiles/minimal/minimal.install +++ b/profiles/minimal/minimal.install @@ -79,7 +79,7 @@ function minimal_install() { $query->execute(); // Set front page to "node". - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); // Allow visitor account creation, but with administrative approval. variable_set('user_register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL); diff --git a/profiles/standard/standard.install b/profiles/standard/standard.install index eef8d0c..e70052e 100644 --- a/profiles/standard/standard.install +++ b/profiles/standard/standard.install @@ -206,7 +206,7 @@ function standard_install() { $query->execute(); // Set front page to "node". - variable_set('site_frontpage', 'node'); + config('system.site')->set('page.front', 'node')->save(); // Insert default pre-defined node types into the database. For a complete // list of available node type attributes, refer to the node type API