' . t('When caching is enabled, anonymous user sessions are only saved to the database when needed, so the "Who\'s online" block does not display the number of anonymous users.') . '
';
+ }
+
+}
+
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ */
+function block_form_system_themes_form_alter(&$form, &$form_state) {
+ $form['#submit'][] = 'block_system_themes_form_submit';
+}
+
Index: modules/block/block.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.info,v
retrieving revision 1.12
diff -u -p -r1.12 block.info
--- modules/block/block.info 3 Feb 2009 12:30:14 -0000 1.12
+++ modules/block/block.info 21 May 2009 23:14:47 -0000
@@ -8,3 +8,7 @@ core = 7.x
files[] = block.module
files[] = block.admin.inc
files[] = block.install
+files[] = block.registry.inc
+files[] = block.user.inc
+files[] = block.block.inc
+files[] = block.form.inc
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.332
diff -u -p -r1.332 block.module
--- modules/block/block.module 16 May 2009 15:23:15 -0000 1.332
+++ modules/block/block.module 21 May 2009 23:14:47 -0000
@@ -88,90 +88,6 @@ function block_help($path, $arg) {
}
/**
- * Implementation of hook_theme().
- */
-function block_theme() {
- return array(
- 'block' => array(
- 'arguments' => array('block' => NULL),
- 'template' => 'block',
- ),
- 'block_admin_display_form' => array(
- 'template' => 'block-admin-display-form',
- 'arguments' => array('form' => NULL),
- ),
- );
-}
-
-/**
- * Implementation of hook_perm().
- */
-function block_perm() {
- return array(
- 'administer blocks' => array(
- 'title' => t('Administer blocks'),
- 'description' => t('Select which blocks are displayed, and arrange them on the page.'),
- ),
- );
-}
-
-/**
- * Implementation of hook_menu().
- */
-function block_menu() {
- $items['admin/build/block'] = array(
- 'title' => 'Blocks',
- 'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
- 'page callback' => 'block_admin_display',
- 'access arguments' => array('administer blocks'),
- );
- $items['admin/build/block/list'] = array(
- 'title' => 'List',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items['admin/build/block/list/js'] = array(
- 'title' => 'JavaScript List Form',
- 'page callback' => 'block_admin_display_js',
- 'access arguments' => array('administer blocks'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/build/block/configure'] = array(
- 'title' => 'Configure block',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('block_admin_configure'),
- 'access arguments' => array('administer blocks'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/build/block/delete'] = array(
- 'title' => 'Delete block',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('block_box_delete'),
- 'access arguments' => array('administer blocks'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/build/block/add'] = array(
- 'title' => 'Add block',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('block_add_block_form'),
- 'access arguments' => array('administer blocks'),
- 'type' => MENU_LOCAL_TASK,
- );
- $default = variable_get('theme_default', 'garland');
- foreach (list_themes() as $key => $theme) {
- $items['admin/build/block/list/' . $key] = array(
- 'title' => check_plain($theme->info['name']),
- 'page arguments' => array($key),
- 'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
- 'weight' => $key == $default ? -10 : 0,
- 'access callback' => '_block_themes_access',
- 'access arguments' => array($theme),
- );
- }
- return $items;
-}
-
-/**
* Menu item access callback - only admin or enabled themes can be accessed.
*/
function _block_themes_access($theme) {
@@ -179,41 +95,6 @@ function _block_themes_access($theme) {
}
/**
- * Implementation of hook_block_list().
- */
-function block_block_list() {
- $blocks = array();
-
- $result = db_query('SELECT bid, info FROM {box} ORDER BY info');
- while ($block = db_fetch_object($result)) {
- $blocks[$block->bid]['info'] = $block->info;
- // Not worth caching.
- $blocks[$block->bid]['cache'] = BLOCK_NO_CACHE;
- }
- return $blocks;
-}
-
-/**
- * Implementation of hook_block_configure().
- */
-function block_block_configure($delta = 0, $edit = array()) {
- $box = array('format' => FILTER_FORMAT_DEFAULT);
- if ($delta) {
- $box = block_box_get($delta);
- }
- if (filter_access($box['format'])) {
- return block_box_form($box);
- }
-}
-
-/**
- * Implementation of hook_block_save().
- */
-function block_block_save($delta = 0, $edit = array()) {
- block_box_save($edit, $delta);
-}
-
-/**
* Implementation of hook_block_view().
*
* Generates the administrator-defined blocks for display.
@@ -403,84 +284,6 @@ function block_box_save($edit, $delta) {
}
/**
- * Implementation of hook_user_form().
- */
-function block_user_form(&$edit, &$account, $category = NULL) {
- if ($category == 'account') {
- $rids = array_keys($account->roles);
- $result = db_query("SELECT DISTINCT b.* FROM {block} b LEFT JOIN {block_role} r ON b.module = r.module AND b.delta = r.delta WHERE b.status = 1 AND b.custom <> 0 AND (r.rid IN (:rids) OR r.rid IS NULL) ORDER BY b.weight, b.module", array(':rids' => $rids));
- $form['block'] = array('#type' => 'fieldset', '#title' => t('Block configuration'), '#weight' => 3, '#collapsible' => TRUE, '#tree' => TRUE);
- while ($block = db_fetch_object($result)) {
- $data = module_invoke($block->module, 'block_list');
- if ($data[$block->delta]['info']) {
- $return = TRUE;
- $form['block'][$block->module][$block->delta] = array('#type' => 'checkbox', '#title' => check_plain($data[$block->delta]['info']), '#default_value' => isset($account->block[$block->module][$block->delta]) ? $account->block[$block->module][$block->delta] : ($block->custom == 1));
- }
- }
-
- if (!empty($return)) {
- return $form;
- }
- }
-}
-
-/**
- * Implementation of hook_user_validate().
- */
-function block_user_validate(&$edit, &$account, $category = NULL) {
- if (empty($edit['block'])) {
- $edit['block'] = array();
- }
- return $edit;
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function block_form_system_performance_settings_alter(&$form, &$form_state) {
-
- // Add the block cache fieldset on the performance settings page.
- $form['block_cache'] = array(
- '#type' => 'fieldset',
- '#title' => t('Block cache'),
- '#description' => t('Enabling the block cache can offer a performance increase for all users by preventing blocks from being reconstructed on each page load. If the page cache is also enabled, performance increases from enabling the block cache will mainly benefit authenticated users.'),
- '#weight' => 0,
- );
-
- $form['block_cache']['block_cache'] = array(
- '#type' => 'radios',
- '#title' => t('Block cache'),
- '#default_value' => variable_get('block_cache', CACHE_DISABLED),
- '#options' => array(CACHE_DISABLED => t('Disabled'), CACHE_NORMAL => t('Enabled (recommended)')),
- '#disabled' => count(module_implements('node_grants')),
- '#description' => t('Note that block caching is inactive when modules defining content access restrictions are enabled.'),
- );
-
- // Check if the "Who's online" block is enabled.
- $online_block_enabled = db_select('block')
- ->condition('module', 'user')
- ->condition('delta', 'online')
- ->condition('status', 1)
- ->countQuery()
- ->execute()
- ->fetchField();
-
- // If the "Who's online" block is enabled, append some descriptive text to
- // the end of the form description.
- if ($online_block_enabled) {
- $form['page_cache']['cache']['#description'] .= '
' . t('When caching is enabled, anonymous user sessions are only saved to the database when needed, so the "Who\'s online" block does not display the number of anonymous users.') . '
';
- }
-
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function block_form_system_themes_form_alter(&$form, &$form_state) {
- $form['#submit'][] = 'block_system_themes_form_submit';
-}
-
-/**
* Initialize blocks for enabled themes.
*/
function block_system_themes_form_submit(&$form, &$form_state) {
@@ -726,13 +529,6 @@ function _block_get_cache_id($block) {
}
/**
- * Implementation of hook_flush_caches().
- */
-function block_flush_caches() {
- return array('cache_block');
-}
-
-/**
* Process variables for block.tpl.php
*
* Prepare the values passed to the theme_block function to be passed
Index: modules/block/block.registry.inc
===================================================================
RCS file: modules/block/block.registry.inc
diff -N modules/block/block.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/block/block.registry.inc 21 May 2009 23:14:05 -0000
@@ -0,0 +1,87 @@
+ 'Blocks',
+ 'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
+ 'page callback' => 'block_admin_display',
+ 'access arguments' => array('administer blocks'),
+ );
+ $items['admin/build/block/list'] = array(
+ 'title' => 'List',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -10,
+ );
+ $items['admin/build/block/list/js'] = array(
+ 'title' => 'JavaScript List Form',
+ 'page callback' => 'block_admin_display_js',
+ 'access arguments' => array('administer blocks'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/build/block/configure'] = array(
+ 'title' => 'Configure block',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('block_admin_configure'),
+ 'access arguments' => array('administer blocks'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/build/block/delete'] = array(
+ 'title' => 'Delete block',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('block_box_delete'),
+ 'access arguments' => array('administer blocks'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/build/block/add'] = array(
+ 'title' => 'Add block',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('block_add_block_form'),
+ 'access arguments' => array('administer blocks'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $default = variable_get('theme_default', 'garland');
+ foreach (list_themes() as $key => $theme) {
+ $items['admin/build/block/list/' . $key] = array(
+ 'title' => check_plain($theme->info['name']),
+ 'page arguments' => array($key),
+ 'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+ 'weight' => $key == $default ? -10 : 0,
+ 'access callback' => '_block_themes_access',
+ 'access arguments' => array($theme),
+ );
+ }
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function block_theme() {
+ return array(
+ 'block' => array(
+ 'arguments' => array('block' => NULL),
+ 'template' => 'block',
+ ),
+ 'block_admin_display_form' => array(
+ 'template' => 'block-admin-display-form',
+ 'arguments' => array('form' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_flush_caches().
+ */
+function block_flush_caches() {
+ return array('cache_block');
+}
+
Index: modules/block/block.user.inc
===================================================================
RCS file: modules/block/block.user.inc
diff -N modules/block/block.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/block/block.user.inc 21 May 2009 23:14:17 -0000
@@ -0,0 +1,52 @@
+ array(
+ 'title' => t('Administer blocks'),
+ 'description' => t('Select which blocks are displayed, and arrange them on the page.'),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_user_form().
+ */
+function block_user_form(&$edit, &$account, $category = NULL) {
+ if ($category == 'account') {
+ $rids = array_keys($account->roles);
+ $result = db_query("SELECT DISTINCT b.* FROM {block} b LEFT JOIN {block_role} r ON b.module = r.module AND b.delta = r.delta WHERE b.status = 1 AND b.custom <> 0 AND (r.rid IN (:rids) OR r.rid IS NULL) ORDER BY b.weight, b.module", array(':rids' => $rids));
+ $form['block'] = array('#type' => 'fieldset', '#title' => t('Block configuration'), '#weight' => 3, '#collapsible' => TRUE, '#tree' => TRUE);
+ while ($block = db_fetch_object($result)) {
+ $data = module_invoke($block->module, 'block_list');
+ if ($data[$block->delta]['info']) {
+ $return = TRUE;
+ $form['block'][$block->module][$block->delta] = array('#type' => 'checkbox', '#title' => check_plain($data[$block->delta]['info']), '#default_value' => isset($account->block[$block->module][$block->delta]) ? $account->block[$block->module][$block->delta] : ($block->custom == 1));
+ }
+ }
+
+ if (!empty($return)) {
+ return $form;
+ }
+ }
+}
+
+/**
+ * Implementation of hook_user_validate().
+ */
+function block_user_validate(&$edit, &$account, $category = NULL) {
+ if (empty($edit['block'])) {
+ $edit['block'] = array();
+ }
+ return $edit;
+}
+
Index: modules/blog/blog.block.inc
===================================================================
RCS file: modules/blog/blog.block.inc
diff -N modules/blog/blog.block.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/blog/blog.block.inc 21 May 2009 23:14:25 -0000
@@ -0,0 +1,16 @@
+ 'Blogs',
- 'page callback' => 'blog_page_last',
- 'access arguments' => array('access content'),
- 'type' => MENU_SUGGESTED_ITEM,
- );
- $items['blog/%user_uid_optional'] = array(
- 'title' => 'My blog',
- 'page callback' => 'blog_page_user',
- 'page arguments' => array(1),
- 'access callback' => 'blog_page_user_access',
- 'access arguments' => array(1),
- );
- $items['blog/%user/feed'] = array(
- 'title' => 'Blogs',
- 'page callback' => 'blog_feed_user',
- 'page arguments' => array(1),
- 'access callback' => 'blog_page_user_access',
- 'access arguments' => array(1),
- 'type' => MENU_CALLBACK,
- );
- $items['blog/feed'] = array(
- 'title' => 'Blogs',
- 'page callback' => 'blog_feed_last',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
-}
-
-/**
* Access callback for user blog pages.
*/
function blog_page_user_access($account) {
@@ -173,14 +131,6 @@ function _blog_post_exists($account) {
}
/**
- * Implementation of hook_block_list().
- */
-function blog_block_list() {
- $block['recent']['info'] = t('Recent blog posts');
- return $block;
-}
-
-/**
* Implementation of hook_block_view().
*
* Displays the most recent 10 blog titles.
Index: modules/blog/blog.registry.inc
===================================================================
RCS file: modules/blog/blog.registry.inc
diff -N modules/blog/blog.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/blog/blog.registry.inc 21 May 2009 23:14:04 -0000
@@ -0,0 +1,43 @@
+ 'Blogs',
+ 'page callback' => 'blog_page_last',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_SUGGESTED_ITEM,
+ );
+ $items['blog/%user_uid_optional'] = array(
+ 'title' => 'My blog',
+ 'page callback' => 'blog_page_user',
+ 'page arguments' => array(1),
+ 'access callback' => 'blog_page_user_access',
+ 'access arguments' => array(1),
+ );
+ $items['blog/%user/feed'] = array(
+ 'title' => 'Blogs',
+ 'page callback' => 'blog_feed_user',
+ 'page arguments' => array(1),
+ 'access callback' => 'blog_page_user_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['blog/feed'] = array(
+ 'title' => 'Blogs',
+ 'page callback' => 'blog_feed_last',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
Index: modules/blog/blog.user.inc
===================================================================
RCS file: modules/blog/blog.user.inc
diff -N modules/blog/blog.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/blog/blog.user.inc 21 May 2009 23:14:17 -0000
@@ -0,0 +1,15 @@
+ array(
- 'title' => t('Administer content with blog API'),
- 'description' => t('Manage website content from external tools.'),
- ),
- );
-}
-
-/**
- * Implementation of hook_xmlrpc().
- */
-function blogapi_xmlrpc() {
- return array(
- array(
- 'blogger.getUsersBlogs',
- 'blogapi_blogger_get_users_blogs',
- array('array', 'string', 'string', 'string'),
- t('Returns a list of blogs to which an author has posting privileges.')),
- array(
- 'blogger.getUserInfo',
- 'blogapi_blogger_get_user_info',
- array('struct', 'string', 'string', 'string'),
- t('Returns information about an author in the system.')),
- array(
- 'blogger.newPost',
- 'blogapi_blogger_new_post',
- array('string', 'string', 'string', 'string', 'string', 'string', 'boolean'),
- t('Creates a new post, and optionally publishes it.')),
- array(
- 'blogger.editPost',
- 'blogapi_blogger_edit_post',
- array('boolean', 'string', 'string', 'string', 'string', 'string', 'boolean'),
- t('Updates the information about an existing post.')),
- array(
- 'blogger.getPost',
- 'blogapi_blogger_get_post',
- array('struct', 'string', 'string', 'string', 'string'),
- t('Returns information about a specific post.')),
- array(
- 'blogger.deletePost',
- 'blogapi_blogger_delete_post',
- array('boolean', 'string', 'string', 'string', 'string', 'boolean'),
- t('Deletes a post.')),
- array(
- 'blogger.getRecentPosts',
- 'blogapi_blogger_get_recent_posts',
- array('array', 'string', 'string', 'string', 'string', 'int'),
- t('Returns a list of the most recent posts in the system.')),
- array(
- 'metaWeblog.newPost',
- 'blogapi_metaweblog_new_post',
- array('string', 'string', 'string', 'string', 'struct', 'boolean'),
- t('Creates a new post, and optionally publishes it.')),
- array(
- 'metaWeblog.editPost',
- 'blogapi_metaweblog_edit_post',
- array('boolean', 'string', 'string', 'string', 'struct', 'boolean'),
- t('Updates information about an existing post.')),
- array(
- 'metaWeblog.getPost',
- 'blogapi_metaweblog_get_post',
- array('struct', 'string', 'string', 'string'),
- t('Returns information about a specific post.')),
- array(
- 'metaWeblog.newMediaObject',
- 'blogapi_metaweblog_new_media_object',
- array('string', 'string', 'string', 'string', 'struct'),
- t('Uploads a file to your webserver.')),
- array(
- 'metaWeblog.getCategories',
- 'blogapi_metaweblog_get_category_list',
- array('struct', 'string', 'string', 'string'),
- t('Returns a list of all categories to which the post is assigned.')),
- array(
- 'metaWeblog.getRecentPosts',
- 'blogapi_metaweblog_get_recent_posts',
- array('array', 'string', 'string', 'string', 'int'),
- t('Returns a list of the most recent posts in the system.')),
- array(
- 'mt.getRecentPostTitles',
- 'blogapi_mt_get_recent_post_titles',
- array('array', 'string', 'string', 'string', 'int'),
- t('Returns a bandwidth-friendly list of the most recent posts in the system.')),
- array(
- 'mt.getCategoryList',
- 'blogapi_mt_get_category_list',
- array('array', 'string', 'string', 'string'),
- t('Returns a list of all categories defined in the blog.')),
- array(
- 'mt.getPostCategories',
- 'blogapi_mt_get_post_categories',
- array('array', 'string', 'string', 'string'),
- t('Returns a list of all categories to which the post is assigned.')),
- array(
- 'mt.setPostCategories',
- 'blogapi_mt_set_post_categories',
- array('boolean', 'string', 'string', 'string', 'array'),
- t('Sets the categories for a post.')),
- array(
- 'mt.supportedMethods',
- 'xmlrpc_server_list_methods',
- array('array'),
- t('Retrieve information about the XML-RPC methods supported by the server.')),
- array(
- 'mt.supportedTextFilters',
- 'blogapi_mt_supported_text_filters',
- array('array'),
- t('Retrieve information about the text formatting plugins supported by the server.')),
- array(
- 'mt.publishPost',
- 'blogapi_mt_publish_post',
- array('boolean', 'string', 'string', 'string'),
- t('Publish (rebuild) all of the static files related to an entry from your blog. Equivalent to saving an entry in the system (but without the ping).')));
-}
-
-/**
- * Blogging API callback. Finds the URL of a user's blog.
- */
-function blogapi_blogger_get_users_blogs($appid, $username, $password) {
- $user = blogapi_validate_user($username, $password);
- if ($user->uid) {
- $types = _blogapi_get_node_types();
- $structs = array();
- foreach ($types as $type) {
- $structs[] = array('url' => url('user/' . $user->uid, array('absolute' => TRUE)), 'blogid' => $type, 'blogName' => $user->name . ": " . $type);
- }
-
- return $structs;
- }
- else {
- return blogapi_error($user);
- }
-}
-
-/**
- * Blogging API callback. Returns profile information about a user.
- */
-function blogapi_blogger_get_user_info($appkey, $username, $password) {
- $user = blogapi_validate_user($username, $password);
-
- if ($user->uid) {
- $name = explode(' ', $user->realname ? $user->realname : $user->name, 2);
- return array(
- 'userid' => $user->uid,
- 'lastname' => $name[1],
- 'firstname' => $name[0],
- 'nickname' => $user->name,
- 'email' => $user->mail,
- 'url' => url('user/' . $user->uid, array('absolute' => TRUE)));
- }
- else {
- return blogapi_error($user);
- }
-}
-
-/**
- * Blogging API callback. Inserts a new blog post as a node.
- */
-function blogapi_blogger_new_post($appkey, $blogid, $username, $password, $content, $publish) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- if (($error = _blogapi_validate_blogid($blogid)) !== TRUE) {
- // Return an error if not configured type.
- return $error;
- }
-
- $edit = array();
- $edit['type'] = $blogid;
- // Get the node type defaults.
- $node_type_default = variable_get('node_options_' . $edit['type'], array('status', 'promote'));
- $edit['uid'] = $user->uid;
- $edit['name'] = $user->name;
- $edit['promote'] = in_array('promote', $node_type_default);
- $edit['comment'] = variable_get('comment_' . $edit['type'], 2);
- $edit['revision'] = in_array('revision', $node_type_default);
- $edit['format'] = FILTER_FORMAT_DEFAULT;
- $edit['status'] = $publish;
-
- // Check for bloggerAPI vs. metaWeblogAPI.
- if (is_array($content)) {
- $edit['title'] = $content['title'];
- $edit['body'] = $content['description'];
- _blogapi_mt_extra($edit, $content);
- }
- else {
- $edit['title'] = blogapi_blogger_title($content);
- $edit['body'] = $content;
- }
-
- if (!node_access('create', $edit['type'])) {
- return blogapi_error(t('You do not have permission to create this type of post.'));
- }
-
- if (user_access('administer nodes') && !isset($edit['date'])) {
- $edit['date'] = format_date(REQUEST_TIME, 'custom', 'Y-m-d H:i:s O');
- }
-
- module_invoke_all('node_blogapi_new', $edit);
-
- $valid = blogapi_status_error_check($edit, $publish);
- if ($valid !== TRUE) {
- return $valid;
- }
-
- node_validate($edit);
- if ($errors = form_get_errors()) {
- return blogapi_error(implode("\n", $errors));
- }
-
- $node = node_submit($edit);
- node_save($node);
- if ($node->nid) {
- watchdog('content', '@type: added %title using blog API.', array('@type' => $node->type, '%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
- // blogger.newPost returns a string so we cast the nid to a string by putting it in double quotes.
- return "$node->nid";
- }
-
- return blogapi_error(t('Error storing post.'));
-}
-
-/**
- * Blogging API callback. Modifies the specified blog node.
- */
-function blogapi_blogger_edit_post($appkey, $postid, $username, $password, $content, $publish) {
- $user = blogapi_validate_user($username, $password);
-
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- $node = node_load($postid);
- if (!$node) {
- return blogapi_error(t('n/a'));
- }
- // Let the teaser be re-generated.
- unset($node->teaser);
-
- if (!node_access('update', $node)) {
- return blogapi_error(t('You do not have permission to update this post.'));
- }
- // Save the original status for validation of permissions.
- $original_status = $node->status;
- $node->status = $publish;
-
- // check for bloggerAPI vs. metaWeblogAPI
- if (is_array($content)) {
- $node->title = $content['title'];
- $node->body = $content['description'];
- _blogapi_mt_extra($node, $content);
- }
- else {
- $node->title = blogapi_blogger_title($content);
- $node->body = $content;
- }
-
- module_invoke_all('node_blogapi_edit', $node);
-
- $valid = blogapi_status_error_check($node, $original_status);
- if ($valid !== TRUE) {
- return $valid;
- }
-
- node_validate($node);
- if ($errors = form_get_errors()) {
- return blogapi_error(implode("\n", $errors));
- }
-
- if (user_access('administer nodes') && !isset($edit['date'])) {
- $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
- }
- $node = node_submit($node);
- node_save($node);
- if ($node->nid) {
- watchdog('content', '@type: updated %title using Blog API.', array('@type' => $node->type, '%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
- return TRUE;
- }
-
- return blogapi_error(t('Error storing post.'));
-}
-
-/**
- * Blogging API callback. Returns a specified blog node.
- */
-function blogapi_blogger_get_post($appkey, $postid, $username, $password) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- $node = node_load($postid);
-
- return _blogapi_get_post($node, TRUE);
-}
-
-/**
* Check that the user has permission to save the node with the chosen status.
*
* @return
@@ -349,322 +48,6 @@ function blogapi_status_error_check($nod
/**
- * Blogging API callback. Removes the specified blog node.
- */
-function blogapi_blogger_delete_post($appkey, $postid, $username, $password, $publish) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- node_delete($postid);
- return TRUE;
-}
-
-/**
- * Blogging API callback. Returns the latest few postings in a user's blog. $bodies TRUE
- *
- * returns a bandwidth-friendly list.
- */
-function blogapi_blogger_get_recent_posts($appkey, $blogid, $username, $password, $number_of_posts, $bodies = TRUE) {
- // Remove unused appkey (from bloggerAPI).
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- if (($error = _blogapi_validate_blogid($blogid)) !== TRUE) {
- // Return an error if not configured type.
- return $error;
- }
-
- if ($bodies) {
- $result = db_query_range("SELECT n.nid, n.title, r.body, r.format, n.comment, n.created, u.name FROM {node} n, {node_revision} r, {users} u WHERE n.uid = u.uid AND n.vid = r.vid AND n.type = :type AND n.uid = :uid ORDER BY n.created DESC", array(
- ':type' => $blogid,
- ':uid' => $user->uid
- ), 0, $number_of_posts);
- }
- else {
- $result = db_query_range("SELECT n.nid, n.title, n.created, u.name FROM {node} n, {users} u WHERE n.uid = u.uid AND n.type = :type AND n.uid = :uid ORDER BY n.created DESC", array(
- ':type' => $blogid,
- ':uid' => $user->uid
- ), 0, $number_of_posts);
- }
- $blogs = array();
- foreach ($result as $blog) {
- $blogs[] = _blogapi_get_post($blog, $bodies);
- }
-
- return $blogs;
-}
-
-function blogapi_metaweblog_new_post($blogid, $username, $password, $content, $publish) {
- return blogapi_blogger_new_post('0123456789ABCDEF', $blogid, $username, $password, $content, $publish);
-}
-
-function blogapi_metaweblog_edit_post($postid, $username, $password, $content, $publish) {
- return blogapi_blogger_edit_post('0123456789ABCDEF', $postid, $username, $password, $content, $publish);
-}
-
-function blogapi_metaweblog_get_post($postid, $username, $password) {
- return blogapi_blogger_get_post('01234567890ABCDEF', $postid, $username, $password);
-}
-
-/**
- * Blogging API callback. Inserts a file into Drupal.
- */
-function blogapi_metaweblog_new_media_object($blogid, $username, $password, $file) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- $usersize = 0;
- $uploadsize = 0;
-
- $roles = array_intersect(user_roles(FALSE, 'administer content with blog api'), $user->roles);
-
- foreach ($roles as $rid => $name) {
- $extensions .= ' ' . strtolower(variable_get("blogapi_extensions_$rid", variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp')));
- $usersize = max($usersize, variable_get("blogapi_usersize_$rid", variable_get('blogapi_usersize_default', 1)) * 1024 * 1024);
- $uploadsize = max($uploadsize, variable_get("blogapi_uploadsize_$rid", variable_get('blogapi_uploadsize_default', 1)) * 1024 * 1024);
- }
-
- $filesize = strlen($file['bits']);
-
- if ($filesize > $uploadsize) {
- return blogapi_error(t('It is not possible to upload the file, because it exceeded the maximum filesize of @maxsize.', array('@maxsize' => format_size($uploadsize))));
- }
-
- if (_blogapi_space_used($user->uid) + $filesize > $usersize) {
- return blogapi_error(t('The file can not be attached to this post, because the disk quota of @quota has been reached.', array('@quota' => format_size($usersize))));
- }
-
- // Only allow files with whitelisted extensions and convert remaining dots to
- // underscores to prevent attacks via non-terminal executable extensions with
- // files such as exploit.php.jpg.
-
- $whitelist = array_unique(explode(' ', trim($extensions)));
-
- $name = basename($file['name']);
-
- if ($extension_position = strrpos($name, '.')) {
- $filename = drupal_substr($name, 0, $extension_position);
- $final_extension = drupal_substr($name, $extension_position + 1);
-
- if (!in_array(strtolower($final_extension), $whitelist)) {
- return blogapi_error(t('It is not possible to upload the file, because it is only possible to upload files with the following extensions: @extensions', array('@extensions' => implode(' ', $whitelist))));
- }
-
- $filename = str_replace('.', '_', $filename);
- $filename .= '.' . $final_extension;
- }
-
- $data = $file['bits'];
-
- if (!$data) {
- return blogapi_error(t('No file sent.'));
- }
-
- if (!$file = file_unmanaged_save_data($data, $filename)) {
- return blogapi_error(t('Error storing file.'));
- }
-
- $row = new stdClass();
- $row->uid = $user->uid;
- $row->filepath = $file;
- $row->filesize = $filesize;
-
- drupal_write_record('blogapi_files', $row);
-
- // Return the successful result.
- return array('url' => file_create_url($file), 'struct');
-}
-/**
- * Blogging API callback. Returns a list of the taxonomy terms that can be
- * associated with a blog node.
- */
-function blogapi_metaweblog_get_category_list($blogid, $username, $password) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- if (($error = _blogapi_validate_blogid($blogid)) !== TRUE) {
- // Return an error if not configured type.
- return $error;
- }
-
- $vocabularies = module_invoke('taxonomy', 'get_vocabularies', $blogid, 'vid');
- $categories = array();
- if ($vocabularies) {
- foreach ($vocabularies as $vocabulary) {
- $terms = module_invoke('taxonomy', 'get_tree', $vocabulary->vid);
- foreach ($terms as $term) {
- $term_name = $term->name;
- foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
- $term_name = $parent->name . '/' . $term_name;
- }
- $categories[] = array('categoryName' => $term_name, 'categoryId' => $term->tid);
- }
- }
- }
-
- return $categories;
-}
-
-function blogapi_metaweblog_get_recent_posts($blogid, $username, $password, $number_of_posts) {
- return blogapi_blogger_get_recent_posts('0123456789ABCDEF', $blogid, $username, $password, $number_of_posts, TRUE);
-}
-
-function blogapi_mt_get_recent_post_titles($blogid, $username, $password, $number_of_posts) {
- return blogapi_blogger_get_recent_posts('0123456789ABCDEF', $blogid, $username, $password, $number_of_posts, FALSE);
-}
-
-function blogapi_mt_get_category_list($blogid, $username, $password) {
- return blogapi_metaweblog_get_category_list($blogid, $username, $password);
-}
-
-/**
- * Blogging API callback. Returns a list of the taxonomy terms that are
- * assigned to a particular node.
- */
-function blogapi_mt_get_post_categories($postid, $username, $password) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- $node = node_load($postid);
- $terms = module_invoke('taxonomy', 'node_get_terms', $node, 'tid');
- $categories = array();
- foreach ($terms as $term) {
- $term_name = $term->name;
- foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
- $term_name = $parent->name . '/' . $term_name;
- }
- $categories[] = array('categoryName' => $term_name, 'categoryId' => $term->tid, 'isPrimary' => TRUE);
- }
-
- return $categories;
-}
-
-/**
- * Blogging API callback. Assigns taxonomy terms to a particular node.
- */
-function blogapi_mt_set_post_categories($postid, $username, $password, $categories) {
- $user = blogapi_validate_user($username, $password);
- if (!$user->uid) {
- return blogapi_error($user);
- }
-
- $node = node_load($postid);
- $node->taxonomy = array();
- foreach ($categories as $category) {
- $node->taxonomy[] = $category['categoryId'];
- }
- $validated = blogapi_mt_validate_terms($node);
- if ($validated !== TRUE) {
- return $validated;
- }
- node_save($node);
-
- return TRUE;
-}
-
-/**
- * Blogging API helper - find allowed taxonomy terms for a node type.
- */
-function blogapi_mt_validate_terms($node) {
- // We do a lot of heavy lifting here since taxonomy module doesn't have a
- // stand-alone validation function.
- if (module_exists('taxonomy')) {
- $found_terms = array();
- if (!empty($node->taxonomy)) {
- $term_list = array_unique($node->taxonomy);
- $params = $term_list;
- $params[] = $node->type;
- $result = db_query(db_rewrite_sql("SELECT t.tid, t.vid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_vocabulary_node_type} n ON t.vid = n.vid WHERE t.tid IN (". db_placeholders($term_list) .") AND n.type = '%s'", 't', 'tid'), $params);
- $found_terms = array();
- $found_count = 0;
- while ($term = db_fetch_object($result)) {
- $found_terms[$term->vid][$term->tid] = $term->tid;
- $found_count++;
- }
- // If the counts don't match, some terms are invalid or not accessible to this user.
- if (count($term_list) != $found_count) {
- return blogapi_error(t('Invalid categories submitted.'));
- }
- }
- // Look up all the vocabularies for this node type.
- $result2 = db_query(db_rewrite_sql("SELECT v.vid, v.name, v.required, v.multiple FROM {taxonomy_vocabulary} v INNER JOIN {taxonomy_vocabulary_node_type} n ON v.vid = n.vid WHERE n.type = '%s'", 'v', 'vid'), $node->type);
- // Check each vocabulary associated with this node type.
- while ($vocabulary = db_fetch_object($result2)) {
- // Required vocabularies must have at least one term.
- if ($vocabulary->required && empty($found_terms[$vocabulary->vid])) {
- return blogapi_error(t('A category from the @vocabulary_name vocabulary is required.', array('@vocabulary_name' => $vocabulary->name)));
- }
- // Vocabularies that don't allow multiple terms may have at most one.
- if (!($vocabulary->multiple) && (isset($found_terms[$vocabulary->vid]) && count($found_terms[$vocabulary->vid]) > 1)) {
- return blogapi_error(t('You may only choose one category from the @vocabulary_name vocabulary.'), array('@vocabulary_name' => $vocabulary->name));
- }
- }
- }
- elseif (!empty($node->taxonomy)) {
- return blogapi_error(t('Error saving categories. This feature is not available.'));
- }
- return TRUE;
-}
-
-/**
- * Blogging API callback. Sends a list of available text formats.
- */
-function blogapi_mt_supported_text_filters() {
- // NOTE: we're only using anonymous' formats because the MT spec
- // does not allow for per-user formats.
- $formats = filter_formats();
-
- $filters = array();
- foreach ($formats as $format) {
- $filter['key'] = $format->format;
- $filter['label'] = $format->name;
- $filters[] = $filter;
- }
-
- return $filters;
-}
-
-/**
- * Blogging API callback. Publishes the given node.
- */
-function blogapi_mt_publish_post($postid, $username, $password) {
- $user = blogapi_validate_user($username, $password);
-
- if (!$user->uid) {
- return blogapi_error($user);
- }
- $node = node_load($postid);
-
- if (!$node) {
- return blogapi_error(t('Invalid post.'));
- }
-
- // Nothing needs to be done if already published.
- if ($node->status) {
- return;
- }
-
- if (!node_access('update', $node) || !user_access('administer nodes')) {
- return blogapi_error(t('You do not have permission to update this post.'));
- }
-
- $node->status = 1;
- node_save($node);
-
- return TRUE;
-}
-
-/**
* Prepare an error message for returning to the XMLRPC caller.
*/
function blogapi_error($message) {
@@ -701,21 +84,6 @@ function blogapi_validate_user($username
}
/**
- * For the blogger API, extract the node title from the contents field.
- */
-function blogapi_blogger_title(&$contents) {
- if (preg_match('/(.*?)<\/title>/i', $contents, $title)) {
- $title = strip_tags($title[0]);
- $contents = preg_replace('/.*?<\/title>/i', '', $contents);
- }
- else {
- list($title, $contents) = explode("\n", $contents, 2);
- }
-
- return $title;
-}
-
-/**
* Add some settings to the admin_settings form.
*/
function blogapi_admin_settings() {
@@ -809,28 +177,6 @@ function blogapi_admin_settings() {
}
/**
- * Implementation of hook_menu().
- */
-function blogapi_menu() {
- $items['blogapi/rsd'] = array(
- 'title' => 'RSD',
- 'page callback' => 'blogapi_rsd',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/settings/blogapi'] = array(
- 'title' => 'Blog API',
- 'description' => 'Configure the content types available to external blogging clients.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('blogapi_admin_settings'),
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_NORMAL_ITEM,
- );
-
- return $items;
-}
-
-/**
* Implementation of hook_init().
*/
function blogapi_init() {
Index: modules/blogapi/blogapi.registry.inc
===================================================================
RCS file: modules/blogapi/blogapi.registry.inc
diff -N modules/blogapi/blogapi.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/blogapi/blogapi.registry.inc 21 May 2009 23:14:04 -0000
@@ -0,0 +1,30 @@
+ 'RSD',
+ 'page callback' => 'blogapi_rsd',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/settings/blogapi'] = array(
+ 'title' => 'Blog API',
+ 'description' => 'Configure the content types available to external blogging clients.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('blogapi_admin_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_NORMAL_ITEM,
+ );
+
+ return $items;
+}
+
Index: modules/blogapi/blogapi.user.inc
===================================================================
RCS file: modules/blogapi/blogapi.user.inc
diff -N modules/blogapi/blogapi.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/blogapi/blogapi.user.inc 21 May 2009 23:14:17 -0000
@@ -0,0 +1,20 @@
+ array(
+ 'title' => t('Administer content with blog API'),
+ 'description' => t('Manage website content from external tools.'),
+ ),
+ );
+}
+
Index: modules/blogapi/blogapi.xmlrpc.inc
===================================================================
RCS file: modules/blogapi/blogapi.xmlrpc.inc
diff -N modules/blogapi/blogapi.xmlrpc.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/blogapi/blogapi.xmlrpc.inc 21 May 2009 23:14:44 -0000
@@ -0,0 +1,628 @@
+uid) {
+ $types = _blogapi_get_node_types();
+ $structs = array();
+ foreach ($types as $type) {
+ $structs[] = array('url' => url('user/' . $user->uid, array('absolute' => TRUE)), 'blogid' => $type, 'blogName' => $user->name . ": " . $type);
+ }
+
+ return $structs;
+ }
+ else {
+ return blogapi_error($user);
+ }
+}
+
+/**
+ * Blogging API callback. Returns profile information about a user.
+ */
+function blogapi_blogger_get_user_info($appkey, $username, $password) {
+ $user = blogapi_validate_user($username, $password);
+
+ if ($user->uid) {
+ $name = explode(' ', $user->realname ? $user->realname : $user->name, 2);
+ return array(
+ 'userid' => $user->uid,
+ 'lastname' => $name[1],
+ 'firstname' => $name[0],
+ 'nickname' => $user->name,
+ 'email' => $user->mail,
+ 'url' => url('user/' . $user->uid, array('absolute' => TRUE)));
+ }
+ else {
+ return blogapi_error($user);
+ }
+}
+
+/**
+ * Blogging API callback. Inserts a new blog post as a node.
+ */
+function blogapi_blogger_new_post($appkey, $blogid, $username, $password, $content, $publish) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ if (($error = _blogapi_validate_blogid($blogid)) !== TRUE) {
+ // Return an error if not configured type.
+ return $error;
+ }
+
+ $edit = array();
+ $edit['type'] = $blogid;
+ // Get the node type defaults.
+ $node_type_default = variable_get('node_options_' . $edit['type'], array('status', 'promote'));
+ $edit['uid'] = $user->uid;
+ $edit['name'] = $user->name;
+ $edit['promote'] = in_array('promote', $node_type_default);
+ $edit['comment'] = variable_get('comment_' . $edit['type'], 2);
+ $edit['revision'] = in_array('revision', $node_type_default);
+ $edit['format'] = FILTER_FORMAT_DEFAULT;
+ $edit['status'] = $publish;
+
+ // Check for bloggerAPI vs. metaWeblogAPI.
+ if (is_array($content)) {
+ $edit['title'] = $content['title'];
+ $edit['body'] = $content['description'];
+ _blogapi_mt_extra($edit, $content);
+ }
+ else {
+ $edit['title'] = blogapi_blogger_title($content);
+ $edit['body'] = $content;
+ }
+
+ if (!node_access('create', $edit['type'])) {
+ return blogapi_error(t('You do not have permission to create this type of post.'));
+ }
+
+ if (user_access('administer nodes') && !isset($edit['date'])) {
+ $edit['date'] = format_date(REQUEST_TIME, 'custom', 'Y-m-d H:i:s O');
+ }
+
+ module_invoke_all('node_blogapi_new', $edit);
+
+ $valid = blogapi_status_error_check($edit, $publish);
+ if ($valid !== TRUE) {
+ return $valid;
+ }
+
+ node_validate($edit);
+ if ($errors = form_get_errors()) {
+ return blogapi_error(implode("\n", $errors));
+ }
+
+ $node = node_submit($edit);
+ node_save($node);
+ if ($node->nid) {
+ watchdog('content', '@type: added %title using blog API.', array('@type' => $node->type, '%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
+ // blogger.newPost returns a string so we cast the nid to a string by putting it in double quotes.
+ return "$node->nid";
+ }
+
+ return blogapi_error(t('Error storing post.'));
+}
+
+/**
+ * Blogging API callback. Modifies the specified blog node.
+ */
+function blogapi_blogger_edit_post($appkey, $postid, $username, $password, $content, $publish) {
+ $user = blogapi_validate_user($username, $password);
+
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ $node = node_load($postid);
+ if (!$node) {
+ return blogapi_error(t('n/a'));
+ }
+ // Let the teaser be re-generated.
+ unset($node->teaser);
+
+ if (!node_access('update', $node)) {
+ return blogapi_error(t('You do not have permission to update this post.'));
+ }
+ // Save the original status for validation of permissions.
+ $original_status = $node->status;
+ $node->status = $publish;
+
+ // check for bloggerAPI vs. metaWeblogAPI
+ if (is_array($content)) {
+ $node->title = $content['title'];
+ $node->body = $content['description'];
+ _blogapi_mt_extra($node, $content);
+ }
+ else {
+ $node->title = blogapi_blogger_title($content);
+ $node->body = $content;
+ }
+
+ module_invoke_all('node_blogapi_edit', $node);
+
+ $valid = blogapi_status_error_check($node, $original_status);
+ if ($valid !== TRUE) {
+ return $valid;
+ }
+
+ node_validate($node);
+ if ($errors = form_get_errors()) {
+ return blogapi_error(implode("\n", $errors));
+ }
+
+ if (user_access('administer nodes') && !isset($edit['date'])) {
+ $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+ }
+ $node = node_submit($node);
+ node_save($node);
+ if ($node->nid) {
+ watchdog('content', '@type: updated %title using Blog API.', array('@type' => $node->type, '%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
+ return TRUE;
+ }
+
+ return blogapi_error(t('Error storing post.'));
+}
+
+/**
+ * Blogging API callback. Returns a specified blog node.
+ */
+function blogapi_blogger_get_post($appkey, $postid, $username, $password) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ $node = node_load($postid);
+
+ return _blogapi_get_post($node, TRUE);
+}
+
+/**
+ * Blogging API callback. Removes the specified blog node.
+ */
+function blogapi_blogger_delete_post($appkey, $postid, $username, $password, $publish) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ node_delete($postid);
+ return TRUE;
+}
+
+/**
+ * Blogging API callback. Returns the latest few postings in a user's blog. $bodies TRUE
+ *
+ * returns a bandwidth-friendly list.
+ */
+function blogapi_blogger_get_recent_posts($appkey, $blogid, $username, $password, $number_of_posts, $bodies = TRUE) {
+ // Remove unused appkey (from bloggerAPI).
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ if (($error = _blogapi_validate_blogid($blogid)) !== TRUE) {
+ // Return an error if not configured type.
+ return $error;
+ }
+
+ if ($bodies) {
+ $result = db_query_range("SELECT n.nid, n.title, r.body, r.format, n.comment, n.created, u.name FROM {node} n, {node_revision} r, {users} u WHERE n.uid = u.uid AND n.vid = r.vid AND n.type = :type AND n.uid = :uid ORDER BY n.created DESC", array(
+ ':type' => $blogid,
+ ':uid' => $user->uid
+ ), 0, $number_of_posts);
+ }
+ else {
+ $result = db_query_range("SELECT n.nid, n.title, n.created, u.name FROM {node} n, {users} u WHERE n.uid = u.uid AND n.type = :type AND n.uid = :uid ORDER BY n.created DESC", array(
+ ':type' => $blogid,
+ ':uid' => $user->uid
+ ), 0, $number_of_posts);
+ }
+ $blogs = array();
+ foreach ($result as $blog) {
+ $blogs[] = _blogapi_get_post($blog, $bodies);
+ }
+
+ return $blogs;
+}
+
+function blogapi_metaweblog_new_post($blogid, $username, $password, $content, $publish) {
+ return blogapi_blogger_new_post('0123456789ABCDEF', $blogid, $username, $password, $content, $publish);
+}
+
+function blogapi_metaweblog_edit_post($postid, $username, $password, $content, $publish) {
+ return blogapi_blogger_edit_post('0123456789ABCDEF', $postid, $username, $password, $content, $publish);
+}
+
+function blogapi_metaweblog_get_post($postid, $username, $password) {
+ return blogapi_blogger_get_post('01234567890ABCDEF', $postid, $username, $password);
+}
+
+/**
+ * Blogging API callback. Inserts a file into Drupal.
+ */
+function blogapi_metaweblog_new_media_object($blogid, $username, $password, $file) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ $usersize = 0;
+ $uploadsize = 0;
+
+ $roles = array_intersect(user_roles(FALSE, 'administer content with blog api'), $user->roles);
+
+ foreach ($roles as $rid => $name) {
+ $extensions .= ' ' . strtolower(variable_get("blogapi_extensions_$rid", variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp')));
+ $usersize = max($usersize, variable_get("blogapi_usersize_$rid", variable_get('blogapi_usersize_default', 1)) * 1024 * 1024);
+ $uploadsize = max($uploadsize, variable_get("blogapi_uploadsize_$rid", variable_get('blogapi_uploadsize_default', 1)) * 1024 * 1024);
+ }
+
+ $filesize = strlen($file['bits']);
+
+ if ($filesize > $uploadsize) {
+ return blogapi_error(t('It is not possible to upload the file, because it exceeded the maximum filesize of @maxsize.', array('@maxsize' => format_size($uploadsize))));
+ }
+
+ if (_blogapi_space_used($user->uid) + $filesize > $usersize) {
+ return blogapi_error(t('The file can not be attached to this post, because the disk quota of @quota has been reached.', array('@quota' => format_size($usersize))));
+ }
+
+ // Only allow files with whitelisted extensions and convert remaining dots to
+ // underscores to prevent attacks via non-terminal executable extensions with
+ // files such as exploit.php.jpg.
+
+ $whitelist = array_unique(explode(' ', trim($extensions)));
+
+ $name = basename($file['name']);
+
+ if ($extension_position = strrpos($name, '.')) {
+ $filename = drupal_substr($name, 0, $extension_position);
+ $final_extension = drupal_substr($name, $extension_position + 1);
+
+ if (!in_array(strtolower($final_extension), $whitelist)) {
+ return blogapi_error(t('It is not possible to upload the file, because it is only possible to upload files with the following extensions: @extensions', array('@extensions' => implode(' ', $whitelist))));
+ }
+
+ $filename = str_replace('.', '_', $filename);
+ $filename .= '.' . $final_extension;
+ }
+
+ $data = $file['bits'];
+
+ if (!$data) {
+ return blogapi_error(t('No file sent.'));
+ }
+
+ if (!$file = file_unmanaged_save_data($data, $filename)) {
+ return blogapi_error(t('Error storing file.'));
+ }
+
+ $row = new stdClass();
+ $row->uid = $user->uid;
+ $row->filepath = $file;
+ $row->filesize = $filesize;
+
+ drupal_write_record('blogapi_files', $row);
+
+ // Return the successful result.
+ return array('url' => file_create_url($file), 'struct');
+}
+/**
+ * Blogging API callback. Returns a list of the taxonomy terms that can be
+ * associated with a blog node.
+ */
+function blogapi_metaweblog_get_category_list($blogid, $username, $password) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ if (($error = _blogapi_validate_blogid($blogid)) !== TRUE) {
+ // Return an error if not configured type.
+ return $error;
+ }
+
+ $vocabularies = module_invoke('taxonomy', 'get_vocabularies', $blogid, 'vid');
+ $categories = array();
+ if ($vocabularies) {
+ foreach ($vocabularies as $vocabulary) {
+ $terms = module_invoke('taxonomy', 'get_tree', $vocabulary->vid);
+ foreach ($terms as $term) {
+ $term_name = $term->name;
+ foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
+ $term_name = $parent->name . '/' . $term_name;
+ }
+ $categories[] = array('categoryName' => $term_name, 'categoryId' => $term->tid);
+ }
+ }
+ }
+
+ return $categories;
+}
+
+function blogapi_metaweblog_get_recent_posts($blogid, $username, $password, $number_of_posts) {
+ return blogapi_blogger_get_recent_posts('0123456789ABCDEF', $blogid, $username, $password, $number_of_posts, TRUE);
+}
+
+function blogapi_mt_get_recent_post_titles($blogid, $username, $password, $number_of_posts) {
+ return blogapi_blogger_get_recent_posts('0123456789ABCDEF', $blogid, $username, $password, $number_of_posts, FALSE);
+}
+
+function blogapi_mt_get_category_list($blogid, $username, $password) {
+ return blogapi_metaweblog_get_category_list($blogid, $username, $password);
+}
+
+/**
+ * Blogging API callback. Returns a list of the taxonomy terms that are
+ * assigned to a particular node.
+ */
+function blogapi_mt_get_post_categories($postid, $username, $password) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ $node = node_load($postid);
+ $terms = module_invoke('taxonomy', 'node_get_terms', $node, 'tid');
+ $categories = array();
+ foreach ($terms as $term) {
+ $term_name = $term->name;
+ foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
+ $term_name = $parent->name . '/' . $term_name;
+ }
+ $categories[] = array('categoryName' => $term_name, 'categoryId' => $term->tid, 'isPrimary' => TRUE);
+ }
+
+ return $categories;
+}
+
+/**
+ * Blogging API callback. Assigns taxonomy terms to a particular node.
+ */
+function blogapi_mt_set_post_categories($postid, $username, $password, $categories) {
+ $user = blogapi_validate_user($username, $password);
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+
+ $node = node_load($postid);
+ $node->taxonomy = array();
+ foreach ($categories as $category) {
+ $node->taxonomy[] = $category['categoryId'];
+ }
+ $validated = blogapi_mt_validate_terms($node);
+ if ($validated !== TRUE) {
+ return $validated;
+ }
+ node_save($node);
+
+ return TRUE;
+}
+
+/**
+ * Blogging API helper - find allowed taxonomy terms for a node type.
+ */
+function blogapi_mt_validate_terms($node) {
+ // We do a lot of heavy lifting here since taxonomy module doesn't have a
+ // stand-alone validation function.
+ if (module_exists('taxonomy')) {
+ $found_terms = array();
+ if (!empty($node->taxonomy)) {
+ $term_list = array_unique($node->taxonomy);
+ $params = $term_list;
+ $params[] = $node->type;
+ $result = db_query(db_rewrite_sql("SELECT t.tid, t.vid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_vocabulary_node_type} n ON t.vid = n.vid WHERE t.tid IN (". db_placeholders($term_list) .") AND n.type = '%s'", 't', 'tid'), $params);
+ $found_terms = array();
+ $found_count = 0;
+ while ($term = db_fetch_object($result)) {
+ $found_terms[$term->vid][$term->tid] = $term->tid;
+ $found_count++;
+ }
+ // If the counts don't match, some terms are invalid or not accessible to this user.
+ if (count($term_list) != $found_count) {
+ return blogapi_error(t('Invalid categories submitted.'));
+ }
+ }
+ // Look up all the vocabularies for this node type.
+ $result2 = db_query(db_rewrite_sql("SELECT v.vid, v.name, v.required, v.multiple FROM {taxonomy_vocabulary} v INNER JOIN {taxonomy_vocabulary_node_type} n ON v.vid = n.vid WHERE n.type = '%s'", 'v', 'vid'), $node->type);
+ // Check each vocabulary associated with this node type.
+ while ($vocabulary = db_fetch_object($result2)) {
+ // Required vocabularies must have at least one term.
+ if ($vocabulary->required && empty($found_terms[$vocabulary->vid])) {
+ return blogapi_error(t('A category from the @vocabulary_name vocabulary is required.', array('@vocabulary_name' => $vocabulary->name)));
+ }
+ // Vocabularies that don't allow multiple terms may have at most one.
+ if (!($vocabulary->multiple) && (isset($found_terms[$vocabulary->vid]) && count($found_terms[$vocabulary->vid]) > 1)) {
+ return blogapi_error(t('You may only choose one category from the @vocabulary_name vocabulary.'), array('@vocabulary_name' => $vocabulary->name));
+ }
+ }
+ }
+ elseif (!empty($node->taxonomy)) {
+ return blogapi_error(t('Error saving categories. This feature is not available.'));
+ }
+ return TRUE;
+}
+
+/**
+ * Blogging API callback. Sends a list of available text formats.
+ */
+function blogapi_mt_supported_text_filters() {
+ // NOTE: we're only using anonymous' formats because the MT spec
+ // does not allow for per-user formats.
+ $formats = filter_formats();
+
+ $filters = array();
+ foreach ($formats as $format) {
+ $filter['key'] = $format->format;
+ $filter['label'] = $format->name;
+ $filters[] = $filter;
+ }
+
+ return $filters;
+}
+
+/**
+ * Blogging API callback. Publishes the given node.
+ */
+function blogapi_mt_publish_post($postid, $username, $password) {
+ $user = blogapi_validate_user($username, $password);
+
+ if (!$user->uid) {
+ return blogapi_error($user);
+ }
+ $node = node_load($postid);
+
+ if (!$node) {
+ return blogapi_error(t('Invalid post.'));
+ }
+
+ // Nothing needs to be done if already published.
+ if ($node->status) {
+ return;
+ }
+
+ if (!node_access('update', $node) || !user_access('administer nodes')) {
+ return blogapi_error(t('You do not have permission to update this post.'));
+ }
+
+ $node->status = 1;
+ node_save($node);
+
+ return TRUE;
+}
+
+/**
+ * For the blogger API, extract the node title from the contents field.
+ */
+function blogapi_blogger_title(&$contents) {
+ if (preg_match('/(.*?)<\/title>/i', $contents, $title)) {
+ $title = strip_tags($title[0]);
+ $contents = preg_replace('/.*?<\/title>/i', '', $contents);
+ }
+ else {
+ list($title, $contents) = explode("\n", $contents, 2);
+ }
+
+ return $title;
+}
+
Index: modules/book/book.block.inc
===================================================================
RCS file: modules/book/book.block.inc
diff -N modules/book/book.block.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/book/book.block.inc 21 May 2009 23:14:25 -0000
@@ -0,0 +1,47 @@
+ t('Show block on all pages'),
+ 'book pages' => t('Show block only on book pages'),
+ );
+ $form['book_block_mode'] = array(
+ '#type' => 'radios',
+ '#title' => t('Book navigation block display'),
+ '#options' => $options,
+ '#default_value' => variable_get('book_block_mode', 'all pages'),
+ '#description' => t("If Show block on all pages is selected, the block will contain the automatically generated menus for all of the site's books. If Show block only on book pages is selected, the block will contain only the one menu corresponding to the current page's book. In this case, if the current page is not in a book, no block will be displayed. The Page specific visibility settings or other visibility settings can be used in addition to selectively display this block."),
+ );
+
+ return $form;
+}
+
+/**
+ * Implementation of hook_block_save().
+ */
+function book_block_save($delta = '', $edit = array()) {
+ $block = array();
+ variable_set('book_block_mode', $edit['book_block_mode']);
+}
+
Index: modules/book/book.form.inc
===================================================================
RCS file: modules/book/book.form.inc
diff -N modules/book/book.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/book/book.form.inc 21 May 2009 23:14:47 -0000
@@ -0,0 +1,22 @@
+book) && $node->book['has_children']) {
+ $form['book_warning'] = array(
+ '#markup' => '
' . t('%title is part of a book outline, and has associated child pages. If you proceed with deletion, the child pages will be relocated automatically.', array('%title' => $node->title)) . '
',
+ '#weight' => -10,
+ );
+ }
+}
+
Index: modules/book/book.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.info,v
retrieving revision 1.11
diff -u -p -r1.11 book.info
--- modules/book/book.info 13 Oct 2008 19:59:41 -0000 1.11
+++ modules/book/book.info 21 May 2009 23:14:47 -0000
@@ -9,3 +9,8 @@ files[] = book.module
files[] = book.admin.inc
files[] = book.pages.inc
files[] = book.install
+files[] = book.registry.inc
+files[] = book.user.inc
+files[] = book.block.inc
+files[] = book.node.inc
+files[] = book.form.inc
Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.493
diff -u -p -r1.493 book.module
--- modules/book/book.module 9 May 2009 18:28:11 -0000 1.493
+++ modules/book/book.module 21 May 2009 23:14:47 -0000
@@ -7,60 +7,6 @@
*/
/**
- * Implementation of hook_theme().
- */
-function book_theme() {
- return array(
- 'book_navigation' => array(
- 'arguments' => array('book_link' => NULL),
- 'template' => 'book-navigation',
- ),
- 'book_export_html' => array(
- 'arguments' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL),
- 'template' => 'book-export-html',
- ),
- 'book_admin_table' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'book_title_link' => array(
- 'arguments' => array('link' => NULL),
- ),
- 'book_all_books_block' => array(
- 'arguments' => array('book_menus' => array()),
- 'template' => 'book-all-books-block',
- ),
- 'book_node_export_html' => array(
- 'arguments' => array('node' => NULL, 'children' => NULL),
- 'template' => 'book-node-export-html',
- ),
- );
-}
-
-/**
- * Implementation of hook_perm().
- */
-function book_perm() {
- return array(
- 'administer book outlines' => array(
- 'title' => t('Administer book outlines'),
- 'description' => t('Manage books through the administration panel.'),
- ),
- 'create new books' => array(
- 'title' => t('Create new books'),
- 'description' => t('Add new top-level books.'),
- ),
- 'add content to books' => array(
- 'title' => t('Add content to books'),
- 'description' => t('Add new content and child pages to books.'),
- ),
- 'access printer-friendly version' => array(
- 'title' => t('Access printer-friendly version'),
- 'description' => t('View a book page and all of its sub-pages as a single document for ease of printing. Can be performance heavy.'),
- ),
- );
-}
-
-/**
* Inject links into $node as needed.
*/
function book_node_view_link($node, $teaser) {
@@ -96,74 +42,6 @@ function book_node_view_link($node, $tea
}
/**
- * Implementation of hook_menu().
- */
-function book_menu() {
- $items['admin/content/book'] = array(
- 'title' => 'Books',
- 'description' => "Manage your site's book outlines.",
- 'page callback' => 'book_admin_overview',
- 'access arguments' => array('administer book outlines'),
- );
- $items['admin/content/book/list'] = array(
- 'title' => 'List',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- $items['admin/content/book/settings'] = array(
- 'title' => 'Settings',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('book_admin_settings'),
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 8,
- );
- $items['admin/content/book/%node'] = array(
- 'title' => 'Re-order book pages and change titles',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('book_admin_edit', 3),
- 'access callback' => '_book_outline_access',
- 'access arguments' => array(3),
- 'type' => MENU_CALLBACK,
- );
- $items['book'] = array(
- 'title' => 'Books',
- 'page callback' => 'book_render',
- 'access arguments' => array('access content'),
- 'type' => MENU_SUGGESTED_ITEM,
- );
- $items['book/export/%/%'] = array(
- 'page callback' => 'book_export',
- 'page arguments' => array(2, 3),
- 'access arguments' => array('access printer-friendly version'),
- 'type' => MENU_CALLBACK,
- );
- $items['node/%node/outline'] = array(
- 'title' => 'Outline',
- 'page callback' => 'book_outline',
- 'page arguments' => array(1),
- 'access callback' => '_book_outline_access',
- 'access arguments' => array(1),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- );
- $items['node/%node/outline/remove'] = array(
- 'title' => 'Remove from outline',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('book_remove_form', 1),
- 'access callback' => '_book_outline_remove_access',
- 'access arguments' => array(1),
- 'type' => MENU_CALLBACK,
- );
- $items['book/js/form'] = array(
- 'page callback' => 'book_form_update',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
-}
-
-/**
* Menu item access callback - determine if the outline tab is accessible.
*/
function _book_outline_access($node) {
@@ -185,17 +63,6 @@ function book_init() {
}
/**
- * Implementation of hook_block_list().
- */
-function book_block_list() {
- $block = array();
- $block['navigation']['info'] = t('Book navigation');
- $block['navigation']['cache'] = BLOCK_CACHE_PER_PAGE | BLOCK_CACHE_PER_ROLE;
-
- return $block;
-}
-
-/**
* Implementation of hook_block_view().
*
* Displays the book table of contents in a block when the current page is a
@@ -249,34 +116,6 @@ function book_block_view($delta = '') {
}
/**
- * Implementation of hook_block_configure().
- */
-function book_block_configure($delta = '') {
- $block = array();
- $options = array(
- 'all pages' => t('Show block on all pages'),
- 'book pages' => t('Show block only on book pages'),
- );
- $form['book_block_mode'] = array(
- '#type' => 'radios',
- '#title' => t('Book navigation block display'),
- '#options' => $options,
- '#default_value' => variable_get('book_block_mode', 'all pages'),
- '#description' => t("If Show block on all pages is selected, the block will contain the automatically generated menus for all of the site's books. If Show block only on book pages is selected, the block will contain only the one menu corresponding to the current page's book. In this case, if the current page is not in a book, no block will be displayed. The Page specific visibility settings or other visibility settings can be used in addition to selectively display this block."),
- );
-
- return $form;
-}
-
-/**
- * Implementation of hook_block_save().
- */
-function book_block_save($delta = '', $edit = array()) {
- $block = array();
- variable_set('book_block_mode', $edit['book_block_mode']);
-}
-
-/**
* Generate the HTML output for a link to a book title when used as a block title.
*
* @ingroup themeable
@@ -735,109 +574,6 @@ function book_page_alter(&$page) {
}
/**
- * Implementation of hook_node_presave().
- */
-function book_node_presave($node) {
- // Always save a revision for non-administrators.
- if (!empty($node->book['bid']) && !user_access('administer nodes')) {
- $node->revision = 1;
- // The database schema requires a log message for every revision.
- if (!isset($node->log)) {
- $node->log = '';
- }
- }
- // Make sure a new node gets a new menu link.
- if (empty($node->nid)) {
- $node->book['mlid'] = NULL;
- }
-}
-
-/**
- * Implementation of hook_node_insert().
- */
-function book_node_insert($node) {
- if (!empty($node->book['bid'])) {
- if ($node->book['bid'] == 'new') {
- // New nodes that are their own book.
- $node->book['bid'] = $node->nid;
- }
- $node->book['nid'] = $node->nid;
- $node->book['menu_name'] = book_menu_name($node->book['bid']);
- _book_update_outline($node);
- }
-}
-
-/**
- * Implementation of hook_node_update().
- */
-function book_node_update($node) {
- if (!empty($node->book['bid'])) {
- if ($node->book['bid'] == 'new') {
- // New nodes that are their own book.
- $node->book['bid'] = $node->nid;
- }
- $node->book['nid'] = $node->nid;
- $node->book['menu_name'] = book_menu_name($node->book['bid']);
- _book_update_outline($node);
- }
-}
-
-/**
- * Implementation of hook_node_delete().
- */
-function book_node_delete($node) {
- if (!empty($node->book['bid'])) {
- if ($node->nid == $node->book['bid']) {
- // Handle deletion of a top-level post.
- $result = db_query("SELECT b.nid FROM {menu_links} ml INNER JOIN {book} b on b.mlid = ml.mlid WHERE ml.plid = :plid", array(
- ':plid' => $node->book['mlid']
- ));
- foreach ($result as $child) {
- $child_node = node_load($child->nid);
- $child_node->book['bid'] = $child_node->nid;
- _book_update_outline($child_node);
- }
- }
- menu_link_delete($node->book['mlid']);
- db_delete('book')
- ->condition('mlid', $node->book['mlid'])
- ->execute();
- }
-}
-
-/**
- * Implementation of hook_node_prepare().
- */
-function book_node_prepare($node) {
- // Prepare defaults for the add/edit form.
- if (empty($node->book) && (user_access('add content to books') || user_access('administer book outlines'))) {
- $node->book = array();
-
- if (empty($node->nid) && isset($_GET['parent']) && is_numeric($_GET['parent'])) {
- // Handle "Add child page" links:
- $parent = book_link_load($_GET['parent']);
-
- if ($parent && $parent['access']) {
- $node->book['bid'] = $parent['bid'];
- $node->book['plid'] = $parent['mlid'];
- $node->book['menu_name'] = $parent['menu_name'];
- }
- }
- // Set defaults.
- $node->book += _book_link_defaults(!empty($node->nid) ? $node->nid : 'new');
- }
- else {
- if (isset($node->book['bid']) && !isset($node->book['original_bid'])) {
- $node->book['original_bid'] = $node->book['bid'];
- }
- }
- // Find the depth limit for the parent select.
- if (isset($node->book['bid']) && !isset($node->book['parent_depth_limit'])) {
- $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
- }
-}
-
-/**
* Find the depth limit for items in the parent select.
*/
function _book_parent_depth_limit($book_link) {
@@ -845,20 +581,6 @@ function _book_parent_depth_limit($book_
}
/**
- * Form altering function for the confirm form for a single node deletion.
- */
-function book_form_node_delete_confirm_alter(&$form, $form_state) {
- $node = node_load($form['nid']['#value']);
-
- if (isset($node->book) && $node->book['has_children']) {
- $form['book_warning'] = array(
- '#markup' => '
' . t('%title is part of a book outline, and has associated child pages. If you proceed with deletion, the child pages will be relocated automatically.', array('%title' => $node->title)) . '
',
- '#weight' => -10,
- );
- }
-}
-
-/**
* Return an array with default values for a book link.
*/
function _book_link_defaults($nid) {
@@ -1065,35 +787,6 @@ function book_type_is_allowed($type) {
}
/**
- * Implementation of hook_node_type().
- *
- * Update book module's persistent variables if the machine-readable name of a
- * node type is changed.
- */
-function book_node_type($op, $type) {
- switch ($op) {
- case 'update':
- if (!empty($type->old_type) && $type->old_type != $type->type) {
- // Update the list of node types that are allowed to be added to books.
- $allowed_types = variable_get('book_allowed_types', array('book'));
- $key = array_search($type->old_type, $allowed_types);
-
- if ($key !== FALSE) {
- $allowed_types[$type->type] = $allowed_types[$key] ? $type->type : 0;
- unset($allowed_types[$key]);
- variable_set('book_allowed_types', $allowed_types);
- }
-
- // Update the setting for the "Add child page" link.
- if (variable_get('book_child_type', 'book') == $type->old_type) {
- variable_set('book_child_type', $type->type);
- }
- }
- break;
- }
-}
-
-/**
* Implementation of hook_help().
*/
function book_help($path, $arg) {
Index: modules/book/book.node.inc
===================================================================
RCS file: modules/book/book.node.inc
diff -N modules/book/book.node.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/book/book.node.inc 21 May 2009 23:14:29 -0000
@@ -0,0 +1,140 @@
+book['bid']) && !user_access('administer nodes')) {
+ $node->revision = 1;
+ // The database schema requires a log message for every revision.
+ if (!isset($node->log)) {
+ $node->log = '';
+ }
+ }
+ // Make sure a new node gets a new menu link.
+ if (empty($node->nid)) {
+ $node->book['mlid'] = NULL;
+ }
+}
+
+/**
+ * Implementation of hook_node_insert().
+ */
+function book_node_insert($node) {
+ if (!empty($node->book['bid'])) {
+ if ($node->book['bid'] == 'new') {
+ // New nodes that are their own book.
+ $node->book['bid'] = $node->nid;
+ }
+ $node->book['nid'] = $node->nid;
+ $node->book['menu_name'] = book_menu_name($node->book['bid']);
+ _book_update_outline($node);
+ }
+}
+
+/**
+ * Implementation of hook_node_update().
+ */
+function book_node_update($node) {
+ if (!empty($node->book['bid'])) {
+ if ($node->book['bid'] == 'new') {
+ // New nodes that are their own book.
+ $node->book['bid'] = $node->nid;
+ }
+ $node->book['nid'] = $node->nid;
+ $node->book['menu_name'] = book_menu_name($node->book['bid']);
+ _book_update_outline($node);
+ }
+}
+
+/**
+ * Implementation of hook_node_delete().
+ */
+function book_node_delete($node) {
+ if (!empty($node->book['bid'])) {
+ if ($node->nid == $node->book['bid']) {
+ // Handle deletion of a top-level post.
+ $result = db_query("SELECT b.nid FROM {menu_links} ml INNER JOIN {book} b on b.mlid = ml.mlid WHERE ml.plid = :plid", array(
+ ':plid' => $node->book['mlid']
+ ));
+ foreach ($result as $child) {
+ $child_node = node_load($child->nid);
+ $child_node->book['bid'] = $child_node->nid;
+ _book_update_outline($child_node);
+ }
+ }
+ menu_link_delete($node->book['mlid']);
+ db_delete('book')
+ ->condition('mlid', $node->book['mlid'])
+ ->execute();
+ }
+}
+
+/**
+ * Implementation of hook_node_prepare().
+ */
+function book_node_prepare($node) {
+ // Prepare defaults for the add/edit form.
+ if (empty($node->book) && (user_access('add content to books') || user_access('administer book outlines'))) {
+ $node->book = array();
+
+ if (empty($node->nid) && isset($_GET['parent']) && is_numeric($_GET['parent'])) {
+ // Handle "Add child page" links:
+ $parent = book_link_load($_GET['parent']);
+
+ if ($parent && $parent['access']) {
+ $node->book['bid'] = $parent['bid'];
+ $node->book['plid'] = $parent['mlid'];
+ $node->book['menu_name'] = $parent['menu_name'];
+ }
+ }
+ // Set defaults.
+ $node->book += _book_link_defaults(!empty($node->nid) ? $node->nid : 'new');
+ }
+ else {
+ if (isset($node->book['bid']) && !isset($node->book['original_bid'])) {
+ $node->book['original_bid'] = $node->book['bid'];
+ }
+ }
+ // Find the depth limit for the parent select.
+ if (isset($node->book['bid']) && !isset($node->book['parent_depth_limit'])) {
+ $node->book['parent_depth_limit'] = _book_parent_depth_limit($node->book);
+ }
+}
+
+/**
+ * Implementation of hook_node_type().
+ *
+ * Update book module's persistent variables if the machine-readable name of a
+ * node type is changed.
+ */
+function book_node_type($op, $type) {
+ switch ($op) {
+ case 'update':
+ if (!empty($type->old_type) && $type->old_type != $type->type) {
+ // Update the list of node types that are allowed to be added to books.
+ $allowed_types = variable_get('book_allowed_types', array('book'));
+ $key = array_search($type->old_type, $allowed_types);
+
+ if ($key !== FALSE) {
+ $allowed_types[$type->type] = $allowed_types[$key] ? $type->type : 0;
+ unset($allowed_types[$key]);
+ variable_set('book_allowed_types', $allowed_types);
+ }
+
+ // Update the setting for the "Add child page" link.
+ if (variable_get('book_child_type', 'book') == $type->old_type) {
+ variable_set('book_child_type', $type->type);
+ }
+ }
+ break;
+ }
+}
+
Index: modules/book/book.registry.inc
===================================================================
RCS file: modules/book/book.registry.inc
diff -N modules/book/book.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/book/book.registry.inc 21 May 2009 23:14:04 -0000
@@ -0,0 +1,106 @@
+ 'Books',
+ 'description' => "Manage your site's book outlines.",
+ 'page callback' => 'book_admin_overview',
+ 'access arguments' => array('administer book outlines'),
+ );
+ $items['admin/content/book/list'] = array(
+ 'title' => 'List',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $items['admin/content/book/settings'] = array(
+ 'title' => 'Settings',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('book_admin_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 8,
+ );
+ $items['admin/content/book/%node'] = array(
+ 'title' => 'Re-order book pages and change titles',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('book_admin_edit', 3),
+ 'access callback' => '_book_outline_access',
+ 'access arguments' => array(3),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['book'] = array(
+ 'title' => 'Books',
+ 'page callback' => 'book_render',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_SUGGESTED_ITEM,
+ );
+ $items['book/export/%/%'] = array(
+ 'page callback' => 'book_export',
+ 'page arguments' => array(2, 3),
+ 'access arguments' => array('access printer-friendly version'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['node/%node/outline'] = array(
+ 'title' => 'Outline',
+ 'page callback' => 'book_outline',
+ 'page arguments' => array(1),
+ 'access callback' => '_book_outline_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ );
+ $items['node/%node/outline/remove'] = array(
+ 'title' => 'Remove from outline',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('book_remove_form', 1),
+ 'access callback' => '_book_outline_remove_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['book/js/form'] = array(
+ 'page callback' => 'book_form_update',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function book_theme() {
+ return array(
+ 'book_navigation' => array(
+ 'arguments' => array('book_link' => NULL),
+ 'template' => 'book-navigation',
+ ),
+ 'book_export_html' => array(
+ 'arguments' => array('title' => NULL, 'contents' => NULL, 'depth' => NULL),
+ 'template' => 'book-export-html',
+ ),
+ 'book_admin_table' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'book_title_link' => array(
+ 'arguments' => array('link' => NULL),
+ ),
+ 'book_all_books_block' => array(
+ 'arguments' => array('book_menus' => array()),
+ 'template' => 'book-all-books-block',
+ ),
+ 'book_node_export_html' => array(
+ 'arguments' => array('node' => NULL, 'children' => NULL),
+ 'template' => 'book-node-export-html',
+ ),
+ );
+}
+
Index: modules/book/book.user.inc
===================================================================
RCS file: modules/book/book.user.inc
diff -N modules/book/book.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/book/book.user.inc 21 May 2009 23:14:17 -0000
@@ -0,0 +1,32 @@
+ array(
+ 'title' => t('Administer book outlines'),
+ 'description' => t('Manage books through the administration panel.'),
+ ),
+ 'create new books' => array(
+ 'title' => t('Create new books'),
+ 'description' => t('Add new top-level books.'),
+ ),
+ 'add content to books' => array(
+ 'title' => t('Add content to books'),
+ 'description' => t('Add new content and child pages to books.'),
+ ),
+ 'access printer-friendly version' => array(
+ 'title' => t('Access printer-friendly version'),
+ 'description' => t('View a book page and all of its sub-pages as a single document for ease of printing. Can be performance heavy.'),
+ ),
+ );
+}
+
Index: modules/color/color.form.inc
===================================================================
RCS file: modules/color/color.form.inc
diff -N modules/color/color.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/color/color.form.inc 21 May 2009 23:14:47 -0000
@@ -0,0 +1,46 @@
+download method is set to public.', array('@url' => url('admin/settings/file-system'))), 'warning');
+ }
+ else {
+ $form['color'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Color scheme'),
+ '#weight' => -1,
+ '#attributes' => array('id' => 'color_scheme_form'),
+ '#theme' => 'color_scheme_form',
+ );
+ $form['color'] += color_scheme_form($form_state, arg(4));
+ $form['#submit'][] = 'color_scheme_form_submit';
+ }
+ }
+}
+
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ */
+function color_form_system_themes_alter(&$form, &$form_state) {
+ _color_theme_select_form_alter($form, $form_state);
+}
+
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ */
+function color_form_system_theme_select_form_alter(&$form, &$form_state) {
+ _color_theme_select_form_alter($form, $form_state);
+}
+
Index: modules/color/color.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/color/color.info,v
retrieving revision 1.9
diff -u -p -r1.9 color.info
--- modules/color/color.info 11 Oct 2008 02:32:40 -0000 1.9
+++ modules/color/color.info 21 May 2009 23:14:47 -0000
@@ -7,3 +7,5 @@ version = VERSION
core = 7.x
files[] = color.module
files[] = color.install
+files[] = color.registry.inc
+files[] = color.form.inc
Index: modules/color/color.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/color/color.module,v
retrieving revision 1.58
diff -u -p -r1.58 color.module
--- modules/color/color.module 16 May 2009 16:08:57 -0000 1.58
+++ modules/color/color.module 21 May 2009 23:14:47 -0000
@@ -17,55 +17,6 @@ function color_help($path, $arg) {
}
/**
- * Implementation of hook_theme().
- */
-function color_theme() {
- return array(
- 'color_scheme_form' => array(
- 'arguments' => array('form' => NULL),
- ),
- );
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function color_form_system_theme_settings_alter(&$form, &$form_state) {
- if (color_get_info(arg(4)) && function_exists('gd_info')) {
- if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) != FILE_DOWNLOADS_PUBLIC) {
- // Disables the color changer when the private download method is used.
- // TODO: This should be solved in a different way. See issue #181003.
- drupal_set_message(t('The color picker only works if the download method is set to public.', array('@url' => url('admin/settings/file-system'))), 'warning');
- }
- else {
- $form['color'] = array(
- '#type' => 'fieldset',
- '#title' => t('Color scheme'),
- '#weight' => -1,
- '#attributes' => array('id' => 'color_scheme_form'),
- '#theme' => 'color_scheme_form',
- );
- $form['color'] += color_scheme_form($form_state, arg(4));
- $form['#submit'][] = 'color_scheme_form_submit';
- }
- }
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function color_form_system_themes_alter(&$form, &$form_state) {
- _color_theme_select_form_alter($form, $form_state);
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function color_form_system_theme_select_form_alter(&$form, &$form_state) {
- _color_theme_select_form_alter($form, $form_state);
-}
-
-/**
* Helper for hook_form_FORM_ID_alter() implementations.
*/
function _color_theme_select_form_alter(&$form, &$form_state) {
Index: modules/color/color.registry.inc
===================================================================
RCS file: modules/color/color.registry.inc
diff -N modules/color/color.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/color/color.registry.inc 21 May 2009 23:14:04 -0000
@@ -0,0 +1,19 @@
+ array(
+ 'arguments' => array('form' => NULL),
+ ),
+ );
+}
+
Index: modules/comment/comment.actions.inc
===================================================================
RCS file: modules/comment/comment.actions.inc
diff -N modules/comment/comment.actions.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/comment/comment.actions.inc 21 May 2009 23:14:12 -0000
@@ -0,0 +1,104 @@
+ array(
+ 'description' => t('Unpublish comment'),
+ 'type' => 'comment',
+ 'configurable' => FALSE,
+ 'hooks' => array(
+ 'comment' => array('insert', 'update'),
+ )
+ ),
+ 'comment_unpublish_by_keyword_action' => array(
+ 'description' => t('Unpublish comment containing keyword(s)'),
+ 'type' => 'comment',
+ 'configurable' => TRUE,
+ 'hooks' => array(
+ 'comment' => array('insert', 'update'),
+ )
+ )
+ );
+}
+
+/**
+ * Drupal action to unpublish a comment.
+ *
+ * @param $context
+ * Keyed array. Must contain the id of the comment if $comment is not passed.
+ * @param $comment
+ * An optional comment object.
+ */
+function comment_unpublish_action($comment, $context = array()) {
+ if (isset($comment->cid)) {
+ $cid = $comment->cid;
+ $subject = $comment->subject;
+ }
+ else {
+ $cid = $context['cid'];
+ $subject = db_query('SELECT subject FROM {comment} WHERE cid = :cid', array(':cid', $cid))->fetchField();
+ }
+ db_update('comment')
+ ->fields(array('status' => COMMENT_NOT_PUBLISHED))
+ ->condition('cid', $cid)
+ ->execute();
+ watchdog('action', 'Unpublished comment %subject.', array('%subject' => $subject));
+}
+
+/**
+ * Form builder; Prepare a form for blacklisted keywords.
+ *
+ * @ingroup forms
+ */
+function comment_unpublish_by_keyword_action_form($context) {
+ $form['keywords'] = array(
+ '#title' => t('Keywords'),
+ '#type' => 'textarea',
+ '#description' => t('The comment will be unpublished if it contains any of the phrases above. Use a case-sensitive, comma-separated list of phrases. Example: funny, bungee jumping, "Company, Inc."'),
+ '#default_value' => isset($context['keywords']) ? drupal_implode_tags($context['keywords']) : '',
+ );
+
+ return $form;
+}
+
+/**
+ * Process comment_unpublish_by_keyword_action_form form submissions.
+ */
+function comment_unpublish_by_keyword_action_submit($form, $form_state) {
+ return array('keywords' => drupal_explode_tags($form_state['values']['keywords']));
+}
+
+/**
+ * Implementation of a configurable Drupal action.
+ *
+ * Unpublish a comment if it contains a certain string.
+ *
+ * @param $context
+ * An array providing more information about the context of the call to this action.
+ * Unused here, since this action currently only supports the insert and update ops of
+ * the comment hook, both of which provide a complete $comment object.
+ * @param $comment
+ * A comment object.
+ */
+function comment_unpublish_by_keyword_action($comment, $context) {
+ foreach ($context['keywords'] as $keyword) {
+ if (strpos($comment->comment, $keyword) !== FALSE || strpos($comment->subject, $keyword) !== FALSE) {
+ db_update('comment')
+ ->fields(array('status' => COMMENT_NOT_PUBLISHED))
+ ->condition('cid', $comment->cid)
+ ->execute();
+ watchdog('action', 'Unpublished comment %subject.', array('%subject' => $comment->subject));
+ break;
+ }
+ }
+}
+
Index: modules/comment/comment.block.inc
===================================================================
RCS file: modules/comment/comment.block.inc
diff -N modules/comment/comment.block.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/comment/comment.block.inc 21 May 2009 23:14:24 -0000
@@ -0,0 +1,39 @@
+ 'select',
+ '#title' => t('Number of recent comments'),
+ '#default_value' => variable_get('comment_block_count', 10),
+ '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
+ '#description' => t('Number of comments displayed in the Recent comments block.'),
+ );
+
+ return $form;
+}
+
+/**
+ * Implementation of hook_block_save().
+ */
+function comment_block_save($delta = '', $edit = array()) {
+ variable_set('comment_block_count', (int)$edit['comment_block_count']);
+}
+
Index: modules/comment/comment.form.inc
===================================================================
RCS file: modules/comment/comment.form.inc
diff -N modules/comment/comment.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/comment/comment.form.inc 21 May 2009 23:14:47 -0000
@@ -0,0 +1,78 @@
+ 'fieldset',
+ '#title' => t('Comment settings'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+ $form['comment']['comment'] = array(
+ '#type' => 'radios',
+ '#title' => t('Default comment setting'),
+ '#default_value' => variable_get('comment_' . $form['#node_type']->type, COMMENT_NODE_OPEN),
+ '#options' => array(t('Hidden'), t('Closed'), t('Open')),
+ '#description' => t('Users with the administer comments permission will be able to override this setting.'),
+ );
+ $form['comment']['comment_default_mode'] = array(
+ '#type' => 'radios',
+ '#title' => t('Default display mode'),
+ '#default_value' => variable_get('comment_default_mode_' . $form['#node_type']->type, COMMENT_MODE_THREADED_EXPANDED),
+ '#options' => _comment_get_modes(),
+ '#description' => t('Expanded views display the body of the comment. Threaded views keep replies together.'),
+ );
+ $form['comment']['comment_default_per_page'] = array(
+ '#type' => 'select',
+ '#title' => t('Comments per page'),
+ '#default_value' => variable_get('comment_default_per_page_' . $form['#node_type']->type, 50),
+ '#options' => _comment_per_page(),
+ '#description' => t('Additional comments will be displayed on separate pages.'),
+ );
+ $form['comment']['comment_anonymous'] = array(
+ '#type' => 'radios',
+ '#title' => t('Anonymous commenting'),
+ '#default_value' => variable_get('comment_anonymous_' . $form['#node_type']->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT),
+ '#options' => array(
+ COMMENT_ANONYMOUS_MAYNOT_CONTACT => t('Anonymous posters may not enter their contact information'),
+ COMMENT_ANONYMOUS_MAY_CONTACT => t('Anonymous posters may leave their contact information'),
+ COMMENT_ANONYMOUS_MUST_CONTACT => t('Anonymous posters must leave their contact information')),
+ '#description' => t('This option is enabled when anonymous users have permission to post comments on the permissions page.', array('@url' => url('admin/user/permissions', array('fragment' => 'module-comment')))),
+ );
+
+ if (!user_access('post comments', drupal_anonymous_user())) {
+ $form['comment']['comment_anonymous']['#disabled'] = TRUE;
+ }
+
+ $form['comment']['comment_subject_field'] = array(
+ '#type' => 'radios',
+ '#title' => t('Comment subject field'),
+ '#default_value' => variable_get('comment_subject_field_' . $form['#node_type']->type, 1),
+ '#options' => array(t('Disabled'), t('Enabled')),
+ '#description' => t('Can users provide a unique subject for their comments?'),
+ );
+ $form['comment']['comment_preview'] = array(
+ '#type' => 'radios',
+ '#title' => t('Preview comment'),
+ '#default_value' => variable_get('comment_preview_' . $form['#node_type']->type, COMMENT_PREVIEW_REQUIRED),
+ '#options' => array(t('Optional'), t('Required')),
+ '#description' => t("Forces a user to look at their comment by clicking on a 'Preview' button before they can actually add the comment"),
+ );
+ $form['comment']['comment_form_location'] = array(
+ '#type' => 'radios',
+ '#title' => t('Location of comment submission form'),
+ '#default_value' => variable_get('comment_form_location_' . $form['#node_type']->type, COMMENT_FORM_SEPARATE_PAGE),
+ '#options' => array(t('Display on separate page'), t('Display below post or comments')),
+ );
+ }
+}
+
Index: modules/comment/comment.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.info,v
retrieving revision 1.9
diff -u -p -r1.9 comment.info
--- modules/comment/comment.info 11 Oct 2008 02:32:41 -0000 1.9
+++ modules/comment/comment.info 21 May 2009 23:14:47 -0000
@@ -9,3 +9,10 @@ files[] = comment.module
files[] = comment.admin.inc
files[] = comment.pages.inc
files[] = comment.install
+files[] = comment.registry.inc
+files[] = comment.actions.inc
+files[] = comment.user.inc
+files[] = comment.block.inc
+files[] = comment.node.inc
+files[] = comment.search.inc
+files[] = comment.form.inc
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.711
diff -u -p -r1.711 comment.module
--- modules/comment/comment.module 21 May 2009 10:34:55 -0000 1.711
+++ modules/comment/comment.module 21 May 2009 23:14:47 -0000
@@ -105,187 +105,6 @@ function comment_help($path, $arg) {
}
/**
- * Implementation of hook_theme().
- */
-function comment_theme() {
- return array(
- 'comment_block' => array(
- 'arguments' => array(),
- ),
- 'comment_preview' => array(
- 'arguments' => array('comment' => NULL, 'node' => NULL, 'links' => array(), 'visible' => 1),
- ),
- 'comment_view' => array(
- 'arguments' => array('comment' => NULL, 'node' => NULL, 'links' => array(), 'visible' => 1),
- ),
- 'comment' => array(
- 'template' => 'comment',
- 'arguments' => array('comment' => NULL, 'node' => NULL, 'links' => array()),
- ),
- 'comment_form_box' => array(
- 'arguments' => array('edit' => NULL, 'title' => NULL),
- ),
- 'comment_folded' => array(
- 'template' => 'comment-folded',
- 'arguments' => array('comment' => NULL),
- ),
- 'comment_flat_collapsed' => array(
- 'arguments' => array('comment' => NULL, 'node' => NULL),
- ),
- 'comment_flat_expanded' => array(
- 'arguments' => array('comment' => NULL, 'node' => NULL),
- ),
- 'comment_thread_collapsed' => array(
- 'arguments' => array('comment' => NULL, 'node' => NULL),
- ),
- 'comment_thread_expanded' => array(
- 'arguments' => array('comment' => NULL, 'node' => NULL),
- ),
- 'comment_post_forbidden' => array(
- 'arguments' => array('nid' => NULL),
- ),
- 'comment_wrapper' => array(
- 'template' => 'comment-wrapper',
- 'arguments' => array('content' => NULL, 'node' => NULL),
- ),
- 'comment_submitted' => array(
- 'arguments' => array('comment' => NULL),
- ),
- );
-}
-
-/**
- * Implementation of hook_menu().
- */
-function comment_menu() {
- $items['admin/content/comment'] = array(
- 'title' => 'Comments',
- 'description' => 'List and edit site comments and the comment approval queue.',
- 'page callback' => 'comment_admin',
- 'access arguments' => array('administer comments'),
- );
- // Tabs begin here.
- $items['admin/content/comment/new'] = array(
- 'title' => 'Published comments',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items['admin/content/comment/approval'] = array(
- 'title' => 'Approval queue',
- 'page arguments' => array('approval'),
- 'access arguments' => array('administer comments'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['comment/delete'] = array(
- 'title' => 'Delete comment',
- 'page callback' => 'comment_delete',
- 'access arguments' => array('administer comments'),
- 'type' => MENU_CALLBACK,
- );
- $items['comment/edit'] = array(
- 'title' => 'Edit comment',
- 'page callback' => 'comment_edit',
- 'access arguments' => array('post comments'),
- 'type' => MENU_CALLBACK,
- );
- $items['comment/reply/%node'] = array(
- 'title' => 'Reply to comment',
- 'page callback' => 'comment_reply',
- 'page arguments' => array(2),
- 'access callback' => 'node_access',
- 'access arguments' => array('view', 2),
- 'type' => MENU_CALLBACK,
- );
- $items['comment/approve'] = array(
- 'title' => 'Approve a comment',
- 'page callback' => 'comment_approve',
- 'page arguments' => array(2),
- 'access arguments' => array('administer comments'),
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
-}
-
-/**
- * Implementation of hook_node_type().
- */
-function comment_node_type($op, $info) {
- $settings = array(
- 'comment',
- 'comment_default_mode',
- 'comment_default_per_page',
- 'comment_anonymous',
- 'comment_subject_field',
- 'comment_preview',
- 'comment_form_location',
- );
-
- switch ($op) {
- case 'delete':
- foreach ($settings as $setting) {
- variable_del($setting . '_' . $info->type);
- }
- break;
- }
-}
-
-/**
- * Implementation of hook_perm().
- */
-function comment_perm() {
- return array(
- 'administer comments' => array(
- 'title' => t('Administer comments'),
- 'description' => t('Manage and approve comments, and configure comment administration settings.'),
- ),
- 'access comments' => array(
- 'title' => t('Access comments'),
- 'description' => t('View comments attached to content.'),
- ),
- 'post comments' => array(
- 'title' => t('Post comments'),
- 'description' => t('Add comments to content (approval required).'),
- ),
- 'post comments without approval' => array(
- 'title' => t('Post comments without approval'),
- 'description' => t('Add comments to content (no approval required).'),
- ),
- );
-}
-
-/**
- * Implementation of hook_block_list().
- */
-function comment_block_list() {
- $blocks['recent']['info'] = t('Recent comments');
-
- return $blocks;
-}
-
-/**
- * Implementation of hook_block_configure().
- */
-function comment_block_configure($delta = '') {
- $form['comment_block_count'] = array(
- '#type' => 'select',
- '#title' => t('Number of recent comments'),
- '#default_value' => variable_get('comment_block_count', 10),
- '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)),
- '#description' => t('Number of comments displayed in the Recent comments block.'),
- );
-
- return $form;
-}
-
-/**
- * Implementation of hook_block_save().
- */
-function comment_block_save($delta = '', $edit = array()) {
- variable_set('comment_block_count', (int)$edit['comment_block_count']);
-}
-
-/**
* Implementation of hook_block_view().
*
* Generates a block with the most recent comments.
@@ -504,76 +323,6 @@ function comment_node_view($node, $tease
}
/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function comment_form_node_type_form_alter(&$form, $form_state) {
- if (isset($form['identity']['type'])) {
- $form['comment'] = array(
- '#type' => 'fieldset',
- '#title' => t('Comment settings'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- );
- $form['comment']['comment'] = array(
- '#type' => 'radios',
- '#title' => t('Default comment setting'),
- '#default_value' => variable_get('comment_' . $form['#node_type']->type, COMMENT_NODE_OPEN),
- '#options' => array(t('Hidden'), t('Closed'), t('Open')),
- '#description' => t('Users with the administer comments permission will be able to override this setting.'),
- );
- $form['comment']['comment_default_mode'] = array(
- '#type' => 'radios',
- '#title' => t('Default display mode'),
- '#default_value' => variable_get('comment_default_mode_' . $form['#node_type']->type, COMMENT_MODE_THREADED_EXPANDED),
- '#options' => _comment_get_modes(),
- '#description' => t('Expanded views display the body of the comment. Threaded views keep replies together.'),
- );
- $form['comment']['comment_default_per_page'] = array(
- '#type' => 'select',
- '#title' => t('Comments per page'),
- '#default_value' => variable_get('comment_default_per_page_' . $form['#node_type']->type, 50),
- '#options' => _comment_per_page(),
- '#description' => t('Additional comments will be displayed on separate pages.'),
- );
- $form['comment']['comment_anonymous'] = array(
- '#type' => 'radios',
- '#title' => t('Anonymous commenting'),
- '#default_value' => variable_get('comment_anonymous_' . $form['#node_type']->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT),
- '#options' => array(
- COMMENT_ANONYMOUS_MAYNOT_CONTACT => t('Anonymous posters may not enter their contact information'),
- COMMENT_ANONYMOUS_MAY_CONTACT => t('Anonymous posters may leave their contact information'),
- COMMENT_ANONYMOUS_MUST_CONTACT => t('Anonymous posters must leave their contact information')),
- '#description' => t('This option is enabled when anonymous users have permission to post comments on the permissions page.', array('@url' => url('admin/user/permissions', array('fragment' => 'module-comment')))),
- );
-
- if (!user_access('post comments', drupal_anonymous_user())) {
- $form['comment']['comment_anonymous']['#disabled'] = TRUE;
- }
-
- $form['comment']['comment_subject_field'] = array(
- '#type' => 'radios',
- '#title' => t('Comment subject field'),
- '#default_value' => variable_get('comment_subject_field_' . $form['#node_type']->type, 1),
- '#options' => array(t('Disabled'), t('Enabled')),
- '#description' => t('Can users provide a unique subject for their comments?'),
- );
- $form['comment']['comment_preview'] = array(
- '#type' => 'radios',
- '#title' => t('Preview comment'),
- '#default_value' => variable_get('comment_preview_' . $form['#node_type']->type, COMMENT_PREVIEW_REQUIRED),
- '#options' => array(t('Optional'), t('Required')),
- '#description' => t("Forces a user to look at their comment by clicking on a 'Preview' button before they can actually add the comment"),
- );
- $form['comment']['comment_form_location'] = array(
- '#type' => 'radios',
- '#title' => t('Location of comment submission form'),
- '#default_value' => variable_get('comment_form_location_' . $form['#node_type']->type, COMMENT_FORM_SEPARATE_PAGE),
- '#options' => array(t('Display on separate page'), t('Display below post or comments')),
- );
- }
-}
-
-/**
* Implementation of hook_form_alter().
*/
function comment_form_alter(&$form, $form_state, $form_id) {
@@ -670,65 +419,6 @@ function comment_node_load($nodes, $type
}
/**
- * Implementation of hook_node_prepare().
- */
-function comment_node_prepare($node) {
- if (!isset($node->comment)) {
- $node->comment = variable_get("comment_$node->type", COMMENT_NODE_OPEN);
- }
-}
-
-/**
- * Implementation of hook_node_insert().
- */
-function comment_node_insert($node) {
- db_insert('node_comment_statistics')
- ->fields(array(
- 'nid' => $node->nid,
- 'last_comment_timestamp' => $node->changed,
- 'last_comment_name' => NULL,
- 'last_comment_uid' => $node->uid,
- 'comment_count' => 0,
- ))
- ->execute();
-}
-
-/**
- * Implementation of hook_node_delete().
- */
-function comment_node_delete($node) {
- db_delete('comment')
- ->condition('nid', $node->nid)
- ->execute();
- db_delete('node_comment_statistics')
- ->condition('nid', $node->nid)
- ->execute();
-}
-
-/**
- * Implementation of hook_node_update_index().
- */
-function comment_node_update_index($node) {
- $text = '';
- $comments = db_query('SELECT subject, comment, format FROM {comment} WHERE nid = :nid AND status = :status', array(
- ':nid' => $node->nid,
- ':status' => COMMENT_PUBLISHED
- ));
- foreach ($comments as $comment) {
- $text .= '
';
+ $output .= theme('table', $header, $row);
+ }
+
+ if ($actions_map) {
+ $output .= drupal_render(drupal_get_form('system_actions_manage_form', $options));
+ }
+
+ return $output;
+}
+
+/**
+ * Define the form for the actions overview page.
+ *
+ * @see system_actions_manage_form_submit()
+ * @ingroup forms
+ * @param $form_state
+ * An associative array containing the current state of the form; not used.
+ * @param $options
+ * An array of configurable actions.
+ * @return
+ * Form definition.
+ */
+function system_actions_manage_form($form_state, $options = array()) {
+ $form['parent'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Make a new advanced action available'),
+ '#prefix' => '
',
+ '#suffix' => '
',
+ );
+ $form['parent']['action'] = array(
+ '#type' => 'select',
+ '#default_value' => '',
+ '#options' => $options,
+ '#description' => '',
+ );
+ $form['parent']['buttons']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Create'),
+ );
+ return $form;
+}
+
+/**
+ * Process system_actions_manage form submissions.
+ */
+function system_actions_manage_form_submit($form, &$form_state) {
+ if ($form_state['values']['action']) {
+ $form_state['redirect'] = 'admin/settings/actions/configure/' . $form_state['values']['action'];
+ }
+}
+
+/**
+ * Menu callback. Create the form for configuration of a single action.
+ *
+ * We provide the "Description" field. The rest of the form
+ * is provided by the action. We then provide the Save button.
+ * Because we are combining unknown form elements with the action
+ * configuration form, we use actions_ prefix on our elements.
+ *
+ * @see system_actions_configure_validate()
+ * @see system_actions_configure_submit()
+ * @param $action
+ * md5 hash of action ID or an integer. If it's an md5 hash, we
+ * are creating a new instance. If it's an integer, we're editing
+ * an existing instance.
+ * @return
+ * Form definition.
+ */
+function system_actions_configure($form_state, $action = NULL) {
+ if ($action === NULL) {
+ drupal_goto('admin/settings/actions');
+ }
+
+ $actions_map = actions_actions_map(actions_list());
+ $edit = array();
+
+ // Numeric action denotes saved instance of a configurable action;
+ // else we are creating a new action instance.
+ if (is_numeric($action)) {
+ $aid = $action;
+ // Load stored parameter values from database.
+ $data = db_query("SELECT * FROM {actions} WHERE aid = :aid", array(':aid' => $aid))->fetch();
+ $edit['actions_description'] = $data->description;
+ $edit['actions_type'] = $data->type;
+ $function = $data->callback;
+ $action = md5($data->callback);
+ $params = unserialize($data->parameters);
+ if ($params) {
+ foreach ($params as $name => $val) {
+ $edit[$name] = $val;
+ }
+ }
+ }
+ else {
+ $function = $actions_map[$action]['callback'];
+ $edit['actions_description'] = $actions_map[$action]['description'];
+ $edit['actions_type'] = $actions_map[$action]['type'];
+ }
+
+ $form['actions_description'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Description'),
+ '#default_value' => $edit['actions_description'],
+ '#maxlength' => '255',
+ '#description' => t('A unique description for this advanced action. This description will be displayed in the interface of modules that integrate with actions, such as Trigger module.'),
+ '#weight' => -10
+ );
+ $action_form = $function . '_form';
+ $form = array_merge($form, $action_form($edit));
+ $form['actions_type'] = array(
+ '#type' => 'value',
+ '#value' => $edit['actions_type'],
+ );
+ $form['actions_action'] = array(
+ '#type' => 'hidden',
+ '#value' => $action,
+ );
+ // $aid is set when configuring an existing action instance.
+ if (isset($aid)) {
+ $form['actions_aid'] = array(
+ '#type' => 'hidden',
+ '#value' => $aid,
+ );
+ }
+ $form['actions_configured'] = array(
+ '#type' => 'hidden',
+ '#value' => '1',
+ );
+ $form['buttons']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#weight' => 13
+ );
+
+ return $form;
+}
+
+/**
+ * Validate system_actions_configure form submissions.
+ */
+function system_actions_configure_validate($form, $form_state) {
+ $function = actions_function_lookup($form_state['values']['actions_action']) . '_validate';
+ // Hand off validation to the action.
+ if (drupal_function_exists($function)) {
+ $function($form, $form_state);
+ }
+}
+
+/**
+ * Process system_actions_configure form submissions.
+ */
+function system_actions_configure_submit($form, &$form_state) {
+ $function = actions_function_lookup($form_state['values']['actions_action']);
+ $submit_function = $function . '_submit';
+
+ // Action will return keyed array of values to store.
+ $params = $submit_function($form, $form_state);
+ $aid = isset($form_state['values']['actions_aid']) ? $form_state['values']['actions_aid'] : NULL;
+
+ actions_save($function, $form_state['values']['actions_type'], $params, $form_state['values']['actions_description'], $aid);
+ drupal_set_message(t('The action has been successfully saved.'));
+
+ $form_state['redirect'] = 'admin/settings/actions/manage';
+}
+
+/**
+ * Create the form for confirmation of deleting an action.
+ *
+ * @ingroup forms
+ * @see system_actions_delete_form_submit()
+ */
+function system_actions_delete_form($form_state, $action) {
+
+ $form['aid'] = array(
+ '#type' => 'hidden',
+ '#value' => $action->aid,
+ );
+ return confirm_form($form,
+ t('Are you sure you want to delete the action %action?', array('%action' => $action->description)),
+ 'admin/settings/actions/manage',
+ t('This cannot be undone.'),
+ t('Delete'), t('Cancel')
+ );
+}
+
+/**
+ * Process system_actions_delete form submissions.
+ *
+ * Post-deletion operations for action deletion.
+ */
+function system_actions_delete_form_submit($form, &$form_state) {
+ $aid = $form_state['values']['aid'];
+ $action = actions_load($aid);
+ actions_delete($aid);
+ $description = check_plain($action->description);
+ watchdog('user', 'Deleted action %aid (%action)', array('%aid' => $aid, '%action' => $description));
+ drupal_set_message(t('Action %action was deleted', array('%action' => $description)));
+ $form_state['redirect'] = 'admin/settings/actions/manage';
+}
+
+/**
+ * Post-deletion operations for deleting action orphans.
+ *
+ * @param $orphaned
+ * An array of orphaned actions.
+ */
+function system_action_delete_orphans_post($orphaned) {
+ foreach ($orphaned as $callback) {
+ drupal_set_message(t("Deleted orphaned action (%action).", array('%action' => $callback)));
+ }
+}
+
+/**
+ * Remove actions that are in the database but not supported by any enabled module.
+ */
+function system_actions_remove_orphans() {
+ actions_synchronize(TRUE);
+ drupal_goto('admin/settings/actions/manage');
+}
+
+/**
+ * Return a form definition so the Send email action can be configured.
+ *
+ * @see system_send_email_action_validate()
+ * @see system_send_email_action_submit()
+ * @param $context
+ * Default values (if we are editing an existing action instance).
+ * @return
+ * Form definition.
+ */
+function system_send_email_action_form($context) {
+ // Set default values for form.
+ if (!isset($context['recipient'])) {
+ $context['recipient'] = '';
+ }
+ if (!isset($context['subject'])) {
+ $context['subject'] = '';
+ }
+ if (!isset($context['message'])) {
+ $context['message'] = '';
+ }
+
+ $form['recipient'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Recipient'),
+ '#default_value' => $context['recipient'],
+ '#maxlength' => '254',
+ '#description' => t('The email address to which the message should be sent OR enter %author if you would like to send an e-mail to the author of the original post.', array('%author' => '%author')),
+ );
+ $form['subject'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Subject'),
+ '#default_value' => $context['subject'],
+ '#maxlength' => '254',
+ '#description' => t('The subject of the message.'),
+ );
+ $form['message'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Message'),
+ '#default_value' => $context['message'],
+ '#cols' => '80',
+ '#rows' => '20',
+ '#description' => t('The message that should be sent. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'),
+ );
+ return $form;
+}
+
+/**
+ * Validate system_send_email_action form submissions.
+ */
+function system_send_email_action_validate($form, $form_state) {
+ $form_values = $form_state['values'];
+ // Validate the configuration form.
+ if (!valid_email_address($form_values['recipient']) && $form_values['recipient'] != '%author') {
+ // We want the literal %author placeholder to be emphasized in the error message.
+ form_set_error('recipient', t('Please enter a valid email address or %author.', array('%author' => '%author')));
+ }
+}
+
+/**
+ * Process system_send_email_action form submissions.
+ */
+function system_send_email_action_submit($form, $form_state) {
+ $form_values = $form_state['values'];
+ // Process the HTML form to store configuration. The keyed array that
+ // we return will be serialized to the database.
+ $params = array(
+ 'recipient' => $form_values['recipient'],
+ 'subject' => $form_values['subject'],
+ 'message' => $form_values['message'],
+ );
+ return $params;
+}
+
+/**
+ * Implementation of a configurable Drupal action. Sends an email.
+ */
+function system_send_email_action($object, $context) {
+ global $user;
+
+ switch ($context['hook']) {
+ case 'node':
+ // Because this is not an action of type 'node' the node
+ // will not be passed as $object, but it will still be available
+ // in $context.
+ $node = $context['node'];
+ break;
+ // The comment hook provides nid, in $context.
+ case 'comment':
+ $comment = $context['comment'];
+ $node = node_load($comment->nid);
+ break;
+ case 'user':
+ // Because this is not an action of type 'user' the user
+ // object is not passed as $object, but it will still be available
+ // in $context.
+ $account = $context['account'];
+ if (isset($context['node'])) {
+ $node = $context['node'];
+ }
+ elseif ($context['recipient'] == '%author') {
+ // If we don't have a node, we don't have a node author.
+ watchdog('error', 'Cannot use %author token in this context.');
+ return;
+ }
+ break;
+ default:
+ // We are being called directly.
+ $node = $object;
+ }
+
+ $recipient = $context['recipient'];
+
+ if (isset($node)) {
+ if (!isset($account)) {
+ $account = user_load($node->uid);
+ }
+ if ($recipient == '%author') {
+ $recipient = $account->mail;
+ }
+ }
+
+ if (!isset($account)) {
+ $account = $user;
+
+ }
+ $language = user_preferred_language($account);
+ $params = array('account' => $account, 'object' => $object, 'context' => $context);
+ if (isset($node)) {
+ $params['node'] = $node;
+ }
+
+ if (drupal_mail('system', 'action_send_email', $recipient, $language, $params)) {
+ watchdog('action', 'Sent email to %recipient', array('%recipient' => $recipient));
+ }
+ else {
+ watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipient));
+ }
+}
+
+/**
+ * Implementation of hook_mail().
+ */
+function system_mail($key, &$message, $params) {
+ $account = $params['account'];
+ $context = $params['context'];
+ $variables = array(
+ '%site_name' => variable_get('site_name', 'Drupal'),
+ '%username' => $account->name,
+ );
+ if ($context['hook'] == 'taxonomy') {
+ $object = $params['object'];
+ $vocabulary = taxonomy_vocabulary_load($object->vid);
+ $variables += array(
+ '%term_name' => $object->name,
+ '%term_description' => $object->description,
+ '%term_id' => $object->tid,
+ '%vocabulary_name' => $vocabulary->name,
+ '%vocabulary_description' => $vocabulary->description,
+ '%vocabulary_id' => $vocabulary->vid,
+ );
+ }
+
+ // Node-based variable translation is only available if we have a node.
+ if (isset($params['node'])) {
+ $node = $params['node'];
+ $variables += array(
+ '%uid' => $node->uid,
+ '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
+ '%node_type' => node_get_types('name', $node),
+ '%title' => $node->title,
+ '%teaser' => $node->teaser,
+ '%body' => $node->body,
+ );
+ }
+ $subject = strtr($context['subject'], $variables);
+ $body = strtr($context['message'], $variables);
+ $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
+ $message['body'][] = drupal_html_to_text($body);
+}
+
+function system_message_action_form($context) {
+ $form['message'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Message'),
+ '#default_value' => isset($context['message']) ? $context['message'] : '',
+ '#required' => TRUE,
+ '#rows' => '8',
+ '#description' => t('The message to be displayed to the current user. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'),
+ );
+ return $form;
+}
+
+function system_message_action_submit($form, $form_state) {
+ return array('message' => $form_state['values']['message']);
+}
+
+/**
+ * A configurable Drupal action. Sends a message to the current user's screen.
+ */
+function system_message_action(&$object, $context = array()) {
+ global $user;
+ $variables = array(
+ '%site_name' => variable_get('site_name', 'Drupal'),
+ '%username' => $user->name ? $user->name : variable_get('anonymous', t('Anonymous')),
+ );
+
+ // This action can be called in any context, but if placeholders
+ // are used a node object must be present to be the source
+ // of substituted text.
+ switch ($context['hook']) {
+ case 'node':
+ // Because this is not an action of type 'node' the node
+ // will not be passed as $object, but it will still be available
+ // in $context.
+ $node = $context['node'];
+ break;
+ // The comment hook also provides the node, in context.
+ case 'comment':
+ $comment = $context['comment'];
+ $node = node_load($comment->nid);
+ break;
+ case 'taxonomy':
+ $vocabulary = taxonomy_vocabulary_load($object->vid);
+ $variables = array_merge($variables, array(
+ '%term_name' => $object->name,
+ '%term_description' => $object->description,
+ '%term_id' => $object->tid,
+ '%vocabulary_name' => $vocabulary->name,
+ '%vocabulary_description' => $vocabulary->description,
+ '%vocabulary_id' => $vocabulary->vid,
+ )
+ );
+ break;
+ default:
+ // We are being called directly.
+ $node = $object;
+ }
+
+ if (isset($node) && is_object($node)) {
+ $variables = array_merge($variables, array(
+ '%uid' => $node->uid,
+ '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
+ '%node_type' => check_plain(node_get_types('name', $node)),
+ '%title' => filter_xss($node->title),
+ '%teaser' => filter_xss($node->teaser),
+ '%body' => filter_xss($node->body),
+ )
+ );
+ }
+ $context['message'] = strtr($context['message'], $variables);
+ drupal_set_message($context['message']);
+}
+
+/**
+ * Implementation of a configurable Drupal action. Redirect user to a URL.
+ */
+function system_goto_action_form($context) {
+ $form['url'] = array(
+ '#type' => 'textfield',
+ '#title' => t('URL'),
+ '#description' => t('The URL to which the user should be redirected. This can be an internal URL like node/1234 or an external URL like http://drupal.org.'),
+ '#default_value' => isset($context['url']) ? $context['url'] : '',
+ '#required' => TRUE,
+ );
+ return $form;
+}
+
+function system_goto_action_submit($form, $form_state) {
+ return array(
+ 'url' => $form_state['values']['url']
+ );
+}
+
+function system_goto_action($object, $context) {
+ drupal_goto($context['url']);
+}
+
+/**
+ * Implementation of a Drupal action.
+ * Blocks the user's IP address.
+ */
+function system_block_ip_action() {
+ $ip = ip_address();
+ db_insert('blocked_ips')
+ ->fields(array('ip' => $ip))
+ ->execute();
+ watchdog('action', 'Banned IP address %ip', array('%ip' => $ip));
+}
+
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.146
diff -u -p -r1.146 system.admin.inc
--- modules/system/system.admin.inc 16 May 2009 20:10:50 -0000 1.146
+++ modules/system/system.admin.inc 21 May 2009 23:14:48 -0000
@@ -2253,3 +2253,67 @@ function theme_system_themes_form($form)
$output .= drupal_render_children($form);
return $output;
}
+/**
+ * Determine if a user is in compact mode.
+ */
+function system_admin_compact_mode() {
+ global $user;
+ return (isset($user->admin_compact_mode)) ? $user->admin_compact_mode : variable_get('admin_compact_mode', FALSE);
+}
+
+/**
+ * Menu callback; Sets whether the admin menu is in compact mode or not.
+ *
+ * @param $mode
+ * Valid values are 'on' and 'off'.
+ */
+function system_admin_compact_page($mode = 'off') {
+ global $user;
+ user_save($user, array('admin_compact_mode' => ($mode == 'on')));
+ drupal_goto(drupal_get_destination());
+}
+
+/**
+ * Generate a list of tasks offered by a specified module.
+ *
+ * @param $module
+ * Module name.
+ * @return
+ * An array of task links.
+ */
+function system_get_module_admin_tasks($module) {
+ static $items;
+
+ if (!isset($items)) {
+ $result = db_query("
+ SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.*
+ FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.router_path = m.path WHERE ml.link_path LIKE 'admin/%' AND hidden >= 0 AND module = 'system' AND m.number_parts > 2", array(), array('fetch' => PDO::FETCH_ASSOC));
+ $items = array();
+ foreach ($result as $item) {
+ _menu_link_translate($item);
+ if ($item['access']) {
+ $items[$item['router_path']] = $item;
+ }
+ }
+ }
+
+ $admin_access = user_access('administer permissions');
+ $admin_tasks = array();
+ $admin_task_count = 0;
+ // Check for permissions.
+ if (in_array($module, module_implements('perm')) && $admin_access) {
+ $admin_tasks[-1] = l(t('Configure permissions'), 'admin/user/permissions', array('fragment' => 'module-' . $module));
+ }
+
+ // Check for menu items that are admin links.
+ if (in_array($module, module_implements('menu')) && $menu = module_invoke($module, 'menu')) {
+ foreach (array_keys($menu) as $path) {
+ if (isset($items[$path])) {
+ $admin_tasks[$items[$path]['title'] . $admin_task_count ++] = l($items[$path]['title'], $path);
+ }
+ }
+ }
+
+ return $admin_tasks;
+}
+
Index: modules/system/system.block.inc
===================================================================
RCS file: modules/system/system.block.inc
diff -N modules/system/system.block.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.block.inc 21 May 2009 23:14:20 -0000
@@ -0,0 +1,71 @@
+ t('Powered by Drupal'),
+ 'weight' => '10',
+ 'cache' => BLOCK_NO_CACHE,
+ );
+ $blocks['help'] = array(
+ 'info' => t('System help'),
+ 'weight' => '5',
+ );
+ // System-defined menu blocks.
+ foreach (menu_list_system_menus() as $menu_name => $title) {
+ $blocks[$menu_name]['info'] = t($title);
+ // Menu blocks can't be cached because each menu item can have
+ // a custom access callback. menu.inc manages its own caching.
+ $blocks[$menu_name]['cache'] = BLOCK_NO_CACHE;
+ }
+ return $blocks;
+}
+
+/**
+ * Implementation of hook_block_configure().
+ */
+function system_block_configure($delta = '') {
+ if ($delta == 'powered-by') {
+ $image_path = 'misc/' . variable_get('drupal_badge_color', 'powered-blue') . '-' . variable_get('drupal_badge_size', '80x15') . '.png';
+ drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
+ // Compile a list of fields to show
+ $form['wrapper']['color'] = array(
+ '#type' => 'select',
+ '#title' => t('Badge color'),
+ '#default_value' => variable_get('drupal_badge_color', 'powered-blue'),
+ '#options' => array('powered-black' => t('Black'), 'powered-blue' => t('Blue'), 'powered-gray' => t('Gray')),
+ );
+ $form['wrapper']['size'] = array(
+ '#type' => 'select',
+ '#title' => t('Badge size'),
+ '#default_value' => variable_get('drupal_badge_size', '80x15'),
+ '#options' => array('80x15' => t('Small'), '88x31' => t('Medium'), '135x42' => t('Large')),
+ );
+ $form['wrapper']['preview'] = array(
+ '#type' => 'item',
+ '#title' => 'Preview',
+ '#markup' => theme('image', $image_path, t('Powered by Drupal, an open source content management system'), t('Powered by Drupal, an open source content management system'), array('class' => 'powered-by-preview'), FALSE),
+ );
+ return $form;
+ }
+}
+
+/**
+ * Implementation of hook_block_save().
+ */
+function system_block_save($delta = '', $edit = NULL) {
+ if ($delta == 'powered-by') {
+ $image_path = 'misc/' . variable_get('drupal_badge_color', 'powered-blue') . '-' . variable_get('drupal_badge_size', '80x15') . '.png';
+ variable_set('drupal_badge_color', $edit['color']);
+ variable_set('drupal_badge_size', $edit['size']);
+ }
+}
+
Index: modules/system/system.cron.inc
===================================================================
RCS file: modules/system/system.cron.inc
diff -N modules/system/system.cron.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.cron.inc 21 May 2009 23:14:40 -0000
@@ -0,0 +1,56 @@
+condition('timestamp', REQUEST_TIME - 3600, '<')
+ ->execute();
+ // Cleanup the batch table.
+ db_delete('batch')
+ ->condition('timestamp', REQUEST_TIME - 864000, '<')
+ ->execute();
+
+ // Remove temporary files that are older than DRUPAL_MAXIMUM_TEMP_FILE_AGE.
+ // Use separate placeholders for the status to avoid a bug in some versions
+ // of PHP. See http://drupal.org/node/352956
+ $result = db_query('SELECT fid FROM {files} WHERE status & :permanent1 <> :permanent2 AND timestamp < :timestamp', array(
+ ':permanent1' => FILE_STATUS_PERMANENT,
+ ':permanent2' => FILE_STATUS_PERMANENT,
+ ':timestamp' => REQUEST_TIME - DRUPAL_MAXIMUM_TEMP_FILE_AGE
+ ));
+ foreach ($result as $row) {
+ if ($file = file_load($row->fid)) {
+ if (!file_delete($file)) {
+ watchdog('file system', 'Could not delete temporary file "%path" during garbage collection', array('%path' => $file->filepath), WATCHDOG_ERROR);
+ }
+ }
+ }
+
+ $core = array('cache', 'cache_filter', 'cache_page', 'cache_form', 'cache_menu');
+ $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
+ foreach ($cache_tables as $table) {
+ cache_clear_all(NULL, $table);
+ }
+
+ // Reset expired items in the default queue implementation table. If that's
+ // not used, this will simply be a no-op.
+ db_update('queue')
+ ->fields(array(
+ 'consumer_id' => 0,
+ 'expire' => 0,
+ ))
+ ->condition('expire', REQUEST_TIME, '<')
+ ->execute();
+}
+
Index: modules/system/system.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.info,v
retrieving revision 1.12
diff -u -p -r1.12 system.info
--- modules/system/system.info 6 May 2009 10:37:28 -0000 1.12
+++ modules/system/system.info 21 May 2009 23:14:40 -0000
@@ -10,3 +10,8 @@ files[] = system.queue.inc
files[] = image.gd.inc
files[] = system.install
required = TRUE
+files[] = system.registry.inc
+files[] = system.actions.inc
+files[] = system.user.inc
+files[] = system.block.inc
+files[] = system.cron.inc
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.694
diff -u -p -r1.694 system.module
--- modules/system/system.module 16 May 2009 18:34:23 -0000 1.694
+++ modules/system/system.module 21 May 2009 23:14:48 -0000
@@ -115,90 +115,6 @@ function system_help($path, $arg) {
}
/**
- * Implementation of hook_theme().
- */
-function system_theme() {
- return array_merge(drupal_common_theme(), array(
- 'system_theme_select_form' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'system_themes_form' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'system_modules_fieldset' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'system_modules_incompatible' => array(
- 'arguments' => array('message' => NULL),
- ),
- 'system_modules_uninstall' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'status_report' => array(
- 'arguments' => array('requirements' => NULL),
- ),
- 'admin_page' => array(
- 'arguments' => array('blocks' => NULL),
- ),
- 'admin_block' => array(
- 'arguments' => array('block' => NULL),
- ),
- 'admin_block_content' => array(
- 'arguments' => array('content' => NULL),
- ),
- 'system_admin_by_module' => array(
- 'arguments' => array('menu_items' => NULL),
- ),
- 'system_powered_by' => array(
- 'arguments' => array('image_path' => NULL),
- ),
- 'meta_generator_html' => array(
- 'arguments' => array('version' => NULL),
- ),
- 'meta_generator_header' => array(
- 'arguments' => array('version' => NULL),
- ),
- 'system_compact_link' => array(),
- ));
-}
-
-/**
- * Implementation of hook_perm().
- */
-function system_perm() {
- return array(
- 'administer site configuration' => array(
- 'title' => t('Administer site configuration'),
- 'description' => t('Configure site-wide settings such as module or theme administration settings.'),
- ),
- 'administer actions' => array(
- 'title' => t('Administer actions'),
- 'description' => t('Manage the actions defined for your site.'),
- ),
- 'administer files' => array(
- 'title' => t('Administer files'),
- 'description' => t('Manage user-uploaded files.'),
- ),
- 'access administration pages' => array(
- 'title' => t('Access administration pages'),
- 'description' => t('View the administration panel and browse the help system.'),
- ),
- 'access site reports' => array(
- 'title' => t('Access site reports'),
- 'description' => t('View reports from system logs and other status information.'),
- ),
- 'select different theme' => array(
- 'title' => t('Select different theme'),
- 'description' => t('Select a theme other than the default theme set by the site administrator.'),
- ),
- 'block IP addresses' => array(
- 'title' => t('Block IP addresses'),
- 'description' => t('Block IP addresses from accessing your site.'),
- ),
- );
-}
-
-/**
* Implementation of hook_rdf_namespaces().
*/
function system_rdf_namespaces() {
@@ -430,331 +346,6 @@ function system_elements() {
}
/**
- * Implementation of hook_menu().
- */
-function system_menu() {
- $items['system/files'] = array(
- 'title' => 'File download',
- 'page callback' => 'file_download',
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
- $items['system/ahah'] = array(
- 'title' => 'AHAH callback',
- 'page callback' => 'form_ahah_callback',
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
- $items['system/timezone'] = array(
- 'title' => 'Time zone',
- 'page callback' => 'system_timezone',
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
- $items['admin'] = array(
- 'title' => 'Administer',
- 'access arguments' => array('access administration pages'),
- 'page callback' => 'system_main_admin_page',
- 'weight' => 9,
- 'menu_name' => 'management',
- );
- $items['admin/compact'] = array(
- 'title' => 'Compact mode',
- 'page callback' => 'system_admin_compact_page',
- 'access arguments' => array('access administration pages'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/by-task'] = array(
- 'title' => 'By task',
- 'page callback' => 'system_main_admin_page',
- 'access arguments' => array('access administration pages'),
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- $items['admin/by-module'] = array(
- 'title' => 'By module',
- 'page callback' => 'system_admin_by_module',
- 'access arguments' => array('access administration pages'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- );
- $items['admin/content'] = array(
- 'title' => 'Content management',
- 'description' => "Manage your site's content.",
- 'position' => 'left',
- 'weight' => -10,
- 'page callback' => 'system_admin_menu_block_page',
- 'access arguments' => array('access administration pages'),
- );
-
- // menu items that are basically just menu blocks
- $items['admin/settings'] = array(
- 'title' => 'Site configuration',
- 'description' => 'Configure site settings.',
- 'position' => 'right',
- 'weight' => -5,
- 'page callback' => 'system_settings_overview',
- 'access arguments' => array('access administration pages'),
- );
- $items['admin/build'] = array(
- 'title' => 'Site building',
- 'description' => 'Control how your site looks and feels.',
- 'position' => 'right',
- 'weight' => -10,
- 'page callback' => 'system_admin_menu_block_page',
- 'access arguments' => array('access administration pages'),
- );
- // Themes:
- $items['admin/build/themes'] = array(
- 'title' => 'Themes',
- 'description' => 'Change which theme your site uses or allows users to set.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_themes_form'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/build/themes/select'] = array(
- 'title' => 'List',
- 'description' => 'Select the default theme for your site.',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -1,
- );
- $items['admin/build/themes/settings'] = array(
- 'title' => 'Configure',
- 'page arguments' => array('system_theme_settings'),
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_LOCAL_TASK,
- );
- // Theme configuration subtabs
- $items['admin/build/themes/settings/global'] = array(
- 'title' => 'Global settings',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -1,
- );
-
- foreach (list_themes() as $theme) {
- $items['admin/build/themes/settings/' . $theme->name] = array(
- 'title' => $theme->info['name'],
- 'page arguments' => array('system_theme_settings', $theme->name),
- 'type' => MENU_LOCAL_TASK,
- 'access callback' => '_system_themes_access',
- 'access arguments' => array($theme),
- );
- }
-
- // Modules:
- $items['admin/build/modules'] = array(
- 'title' => 'Modules',
- 'description' => 'Enable or disable add-on modules for your site.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_modules'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/build/modules/list'] = array(
- 'title' => 'List',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- $items['admin/build/modules/list/confirm'] = array(
- 'title' => 'List',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/build/modules/uninstall'] = array(
- 'title' => 'Uninstall',
- 'page arguments' => array('system_modules_uninstall'),
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['admin/build/modules/uninstall/confirm'] = array(
- 'title' => 'Uninstall',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_CALLBACK,
- );
-
- // Actions:
- $items['admin/settings/actions'] = array(
- 'title' => 'Actions',
- 'description' => 'Manage the actions defined for your site.',
- 'access arguments' => array('administer actions'),
- 'page callback' => 'system_actions_manage'
- );
- $items['admin/settings/actions/manage'] = array(
- 'title' => 'Manage actions',
- 'description' => 'Manage the actions defined for your site.',
- 'page callback' => 'system_actions_manage',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -2,
- );
- $items['admin/settings/actions/configure'] = array(
- 'title' => 'Configure an advanced action',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_actions_configure'),
- 'access arguments' => array('administer actions'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/settings/actions/delete/%actions'] = array(
- 'title' => 'Delete action',
- 'description' => 'Delete an action.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_actions_delete_form', 4),
- 'access arguments' => array('administer actions'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/settings/actions/orphan'] = array(
- 'title' => 'Remove orphans',
- 'page callback' => 'system_actions_remove_orphans',
- 'access arguments' => array('administer actions'),
- 'type' => MENU_CALLBACK,
- );
-
- // IP address blocking.
- $items['admin/settings/ip-blocking'] = array(
- 'title' => 'IP address blocking',
- 'description' => 'Manage blocked IP addresses.',
- 'page callback' => 'system_ip_blocking',
- 'access arguments' => array('block IP addresses'),
- );
- $items['admin/settings/ip-blocking/%'] = array(
- 'title' => 'IP address blocking',
- 'description' => 'Manage blocked IP addresses.',
- 'page callback' => 'system_ip_blocking',
- 'access arguments' => array('block IP addresses'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/settings/ip-blocking/delete/%blocked_ip'] = array(
- 'title' => 'Delete IP address',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_ip_blocking_delete', 4),
- 'access arguments' => array('block IP addresses'),
- 'type' => MENU_CALLBACK,
- );
-
- // Settings:
- $items['admin/settings/site-information'] = array(
- 'title' => 'Site information',
- 'description' => 'Change basic site information, such as the site name, slogan, e-mail address, mission, front page and more.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_site_information_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/logging'] = array(
- 'title' => 'Logging and errors',
- 'description' => "Settings for logging and alerts modules. Various modules can route Drupal's system events to different destinations, such as syslog, database, email, etc.",
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_logging_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/logging/settings'] = array(
- 'title' => 'Settings',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -1,
- );
- $items['admin/settings/performance'] = array(
- 'title' => 'Performance',
- 'description' => 'Enable or disable page caching for anonymous users and set CSS and JS bandwidth optimization options.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_performance_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/file-system'] = array(
- 'title' => 'File system',
- 'description' => 'Tell Drupal where to store uploaded files and how they are accessed.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_file_system_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/image-toolkit'] = array(
- 'title' => 'Image toolkit',
- 'description' => 'Choose which image toolkit to use if you have installed optional toolkits.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_image_toolkit_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/content/rss-publishing'] = array(
- 'title' => 'RSS publishing',
- 'description' => 'Configure the site description, the number of items per feed and whether feeds should be titles/teasers/full-text.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_rss_feeds_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/regional-settings'] = array(
- 'title' => 'Regional settings',
- 'description' => "Settings for how Drupal displays date and time, as well as the system's default time zone.",
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_regional_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/regional-settings/lookup'] = array(
- 'title' => 'Date and time lookup',
- 'type' => MENU_CALLBACK,
- 'page callback' => 'system_date_time_lookup',
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/maintenance-mode'] = array(
- 'title' => 'Maintenance mode',
- 'description' => 'Take the site offline for maintenance or bring it back online.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_site_maintenance_mode'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/clean-urls'] = array(
- 'title' => 'Clean URLs',
- 'description' => 'Enable or disable clean URLs for your site.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('system_clean_url_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/settings/clean-urls/check'] = array(
- 'title' => 'Clean URL check',
- 'page callback' => 'drupal_json',
- 'page arguments' => array(array('status' => TRUE)),
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
-
- // Reports:
- $items['admin/reports'] = array(
- 'title' => 'Reports',
- 'description' => 'View reports from system logs and other status information.',
- 'page callback' => 'system_admin_menu_block_page',
- 'access arguments' => array('access site reports'),
- 'weight' => 5,
- 'position' => 'left',
- );
- $items['admin/reports/status'] = array(
- 'title' => 'Status report',
- 'description' => "Get a status report about your site's operation and any detected problems.",
- 'page callback' => 'system_status',
- 'weight' => 10,
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/reports/status/run-cron'] = array(
- 'title' => 'Run cron',
- 'page callback' => 'system_run_cron',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/reports/status/php'] = array(
- 'title' => 'PHP',
- 'page callback' => 'system_php',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/reports/status/sql'] = array(
- 'title' => 'SQL',
- 'page callback' => 'system_sql',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_CALLBACK,
- );
- // Default page for batch operations
- $items['batch'] = array(
- 'page callback' => 'system_batch_page',
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
- return $items;
-}
-
-/**
* Retrieve a blocked IP address from the database.
*
* @param $iid integer
@@ -808,136 +399,6 @@ function system_preprocess_page(&$variab
}
/**
- * Implementation of hook_user_form().
- */
-function system_user_form(&$edit, &$user, $category = NULL) {
- if ($category == 'account') {
- $form['theme_select'] = system_theme_select_form(t('Selecting a different theme will change the look and feel of the site.'), isset($edit['theme']) ? $edit['theme'] : NULL, 2);
- if (variable_get('configurable_timezones', 1)) {
- system_user_timezone($edit, $form);
- }
- return $form;
- }
-}
-
-/**
- * Implementation of hook_user_register().
- */
-function system_user_register(&$edit, &$user, $category = NULL) {
- if (variable_get('configurable_timezones', 1)) {
- $form = array();
- if (variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) == DRUPAL_USER_TIMEZONE_SELECT) {
- system_user_timezone($edit, $form);
- }
- else {
- $form['timezone'] = array(
- '#type' => 'hidden',
- '#value' => variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) ? '' : variable_get('date_default_timezone', ''),
- );
- }
- return $form;
- }
-}
-
-/**
- * Implementation of hook_user_login().
- */
-function system_user_login(&$edit, &$user, $category = NULL) {
- // If the user has a NULL time zone, notify them to set a time zone.
- if (!$user->timezone && variable_get('configurable_timezones', 1) && variable_get('empty_timezone_message', 0)) {
- drupal_set_message(t('Please configure your account time zone setting.', array('@user-edit' => url("user/$user->uid/edit", array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone')))));
- }
-}
-
-/**
- * Add the time zone field to the user edit and register forms.
- */
-function system_user_timezone(&$edit, &$form) {
- global $user;
- $form['timezone'] = array(
- '#type' => 'fieldset',
- '#title' => t('Locale settings'),
- '#weight' => 6,
- '#collapsible' => TRUE,
- );
- $form['timezone']['timezone'] = array(
- '#type' => 'select',
- '#title' => t('Time zone'),
- '#default_value' => $edit['timezone'] ? $edit['timezone'] : ($edit['uid'] == $user->uid ? variable_get('date_default_timezone', '') : ''),
- '#options' => system_time_zones(($edit['uid'] != $user->uid)),
- '#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
- );
- if (!$edit['timezone'] && $edit['uid'] == $user->uid) {
- $form['timezone']['#description'] = t('Your time zone setting will be automatically detected if possible. Please confirm the selection and click save.');
- $form['timezone']['timezone']['#attributes'] = array('class' => 'timezone-detect');
- drupal_add_js('misc/timezone.js');
- }
-}
-
-/**
- * Implementation of hook_block_list().
- */
-function system_block_list() {
- $blocks['powered-by'] = array(
- 'info' => t('Powered by Drupal'),
- 'weight' => '10',
- 'cache' => BLOCK_NO_CACHE,
- );
- $blocks['help'] = array(
- 'info' => t('System help'),
- 'weight' => '5',
- );
- // System-defined menu blocks.
- foreach (menu_list_system_menus() as $menu_name => $title) {
- $blocks[$menu_name]['info'] = t($title);
- // Menu blocks can't be cached because each menu item can have
- // a custom access callback. menu.inc manages its own caching.
- $blocks[$menu_name]['cache'] = BLOCK_NO_CACHE;
- }
- return $blocks;
-}
-
-/**
- * Implementation of hook_block_configure().
- */
-function system_block_configure($delta = '') {
- if ($delta == 'powered-by') {
- $image_path = 'misc/' . variable_get('drupal_badge_color', 'powered-blue') . '-' . variable_get('drupal_badge_size', '80x15') . '.png';
- drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
- // Compile a list of fields to show
- $form['wrapper']['color'] = array(
- '#type' => 'select',
- '#title' => t('Badge color'),
- '#default_value' => variable_get('drupal_badge_color', 'powered-blue'),
- '#options' => array('powered-black' => t('Black'), 'powered-blue' => t('Blue'), 'powered-gray' => t('Gray')),
- );
- $form['wrapper']['size'] = array(
- '#type' => 'select',
- '#title' => t('Badge size'),
- '#default_value' => variable_get('drupal_badge_size', '80x15'),
- '#options' => array('80x15' => t('Small'), '88x31' => t('Medium'), '135x42' => t('Large')),
- );
- $form['wrapper']['preview'] = array(
- '#type' => 'item',
- '#title' => 'Preview',
- '#markup' => theme('image', $image_path, t('Powered by Drupal, an open source content management system'), t('Powered by Drupal, an open source content management system'), array('class' => 'powered-by-preview'), FALSE),
- );
- return $form;
- }
-}
-
-/**
- * Implementation of hook_block_save().
- */
-function system_block_save($delta = '', $edit = NULL) {
- if ($delta == 'powered-by') {
- $image_path = 'misc/' . variable_get('drupal_badge_color', 'powered-blue') . '-' . variable_get('drupal_badge_size', '80x15') . '.png';
- variable_set('drupal_badge_color', $edit['color']);
- variable_set('drupal_badge_size', $edit['size']);
- }
-}
-
-/**
* Implementation of hook_block_view().
*
* Generate a block with a promotional link to Drupal.org and
@@ -1496,118 +957,6 @@ function confirm_form($form, $question,
}
/**
- * Determine if a user is in compact mode.
- */
-function system_admin_compact_mode() {
- global $user;
- return (isset($user->admin_compact_mode)) ? $user->admin_compact_mode : variable_get('admin_compact_mode', FALSE);
-}
-
-/**
- * Menu callback; Sets whether the admin menu is in compact mode or not.
- *
- * @param $mode
- * Valid values are 'on' and 'off'.
- */
-function system_admin_compact_page($mode = 'off') {
- global $user;
- user_save($user, array('admin_compact_mode' => ($mode == 'on')));
- drupal_goto(drupal_get_destination());
-}
-
-/**
- * Generate a list of tasks offered by a specified module.
- *
- * @param $module
- * Module name.
- * @return
- * An array of task links.
- */
-function system_get_module_admin_tasks($module) {
- static $items;
-
- if (!isset($items)) {
- $result = db_query("
- SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.*
- FROM {menu_links} ml INNER JOIN {menu_router} m ON ml.router_path = m.path WHERE ml.link_path LIKE 'admin/%' AND hidden >= 0 AND module = 'system' AND m.number_parts > 2", array(), array('fetch' => PDO::FETCH_ASSOC));
- $items = array();
- foreach ($result as $item) {
- _menu_link_translate($item);
- if ($item['access']) {
- $items[$item['router_path']] = $item;
- }
- }
- }
-
- $admin_access = user_access('administer permissions');
- $admin_tasks = array();
- $admin_task_count = 0;
- // Check for permissions.
- if (in_array($module, module_implements('perm')) && $admin_access) {
- $admin_tasks[-1] = l(t('Configure permissions'), 'admin/user/permissions', array('fragment' => 'module-' . $module));
- }
-
- // Check for menu items that are admin links.
- if (in_array($module, module_implements('menu')) && $menu = module_invoke($module, 'menu')) {
- foreach (array_keys($menu) as $path) {
- if (isset($items[$path])) {
- $admin_tasks[$items[$path]['title'] . $admin_task_count ++] = l($items[$path]['title'], $path);
- }
- }
- }
-
- return $admin_tasks;
-}
-
-/**
- * Implementation of hook_cron().
- *
- * Remove older rows from flood and batch table. Remove old temporary files.
- */
-function system_cron() {
- // Cleanup the flood.
- db_delete('flood')
- ->condition('timestamp', REQUEST_TIME - 3600, '<')
- ->execute();
- // Cleanup the batch table.
- db_delete('batch')
- ->condition('timestamp', REQUEST_TIME - 864000, '<')
- ->execute();
-
- // Remove temporary files that are older than DRUPAL_MAXIMUM_TEMP_FILE_AGE.
- // Use separate placeholders for the status to avoid a bug in some versions
- // of PHP. See http://drupal.org/node/352956
- $result = db_query('SELECT fid FROM {files} WHERE status & :permanent1 <> :permanent2 AND timestamp < :timestamp', array(
- ':permanent1' => FILE_STATUS_PERMANENT,
- ':permanent2' => FILE_STATUS_PERMANENT,
- ':timestamp' => REQUEST_TIME - DRUPAL_MAXIMUM_TEMP_FILE_AGE
- ));
- foreach ($result as $row) {
- if ($file = file_load($row->fid)) {
- if (!file_delete($file)) {
- watchdog('file system', 'Could not delete temporary file "%path" during garbage collection', array('%path' => $file->filepath), WATCHDOG_ERROR);
- }
- }
- }
-
- $core = array('cache', 'cache_filter', 'cache_page', 'cache_form', 'cache_menu');
- $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
- foreach ($cache_tables as $table) {
- cache_clear_all(NULL, $table);
- }
-
- // Reset expired items in the default queue implementation table. If that's
- // not used, this will simply be a no-op.
- db_update('queue')
- ->fields(array(
- 'consumer_id' => 0,
- 'expire' => 0,
- ))
- ->condition('expire', REQUEST_TIME, '<')
- ->execute();
-}
-
-/**
* Implementation of hook_hook_info().
*/
function system_hook_info() {
@@ -1623,612 +972,6 @@ function system_hook_info() {
}
/**
- * Implementation of hook_action_info().
- */
-function system_action_info() {
- return array(
- 'system_message_action' => array(
- 'type' => 'system',
- 'description' => t('Display a message to the user'),
- 'configurable' => TRUE,
- 'hooks' => array(
- 'node' => array('view', 'insert', 'update', 'delete'),
- 'comment' => array('view', 'insert', 'update', 'delete'),
- 'user' => array('view', 'insert', 'update', 'delete', 'login'),
- 'taxonomy' => array('insert', 'update', 'delete'),
- ),
- ),
- 'system_send_email_action' => array(
- 'description' => t('Send e-mail'),
- 'type' => 'system',
- 'configurable' => TRUE,
- 'hooks' => array(
- 'node' => array('view', 'insert', 'update', 'delete'),
- 'comment' => array('view', 'insert', 'update', 'delete'),
- 'user' => array('view', 'insert', 'update', 'delete', 'login'),
- 'taxonomy' => array('insert', 'update', 'delete'),
- 'cron' => array('run'),
- )
- ),
- 'system_block_ip_action' => array(
- 'description' => t('Ban IP address of current user'),
- 'type' => 'user',
- 'configurable' => FALSE,
- 'hooks' => array(),
- ),
- 'system_goto_action' => array(
- 'description' => t('Redirect to URL'),
- 'type' => 'system',
- 'configurable' => TRUE,
- 'hooks' => array(
- 'node' => array('view', 'insert', 'update', 'delete'),
- 'comment' => array('view', 'insert', 'update', 'delete'),
- 'user' => array('view', 'insert', 'update', 'delete', 'login'),
- )
- )
- );
-}
-
-/**
- * Menu callback. Display an overview of available and configured actions.
- */
-function system_actions_manage() {
- $output = '';
- actions_synchronize();
- $actions = actions_list();
- $actions_map = actions_actions_map($actions);
- $options = array(t('Choose an advanced action'));
- $unconfigurable = array();
-
- foreach ($actions_map as $key => $array) {
- if ($array['configurable']) {
- $options[$key] = $array['description'] . '...';
- }
- else {
- $unconfigurable[] = $array;
- }
- }
-
- $row = array();
- $instances_present = db_query("SELECT aid FROM {actions} WHERE parameters <> ''")->fetchField();
- $header = array(
- array('data' => t('Action type'), 'field' => 'type'),
- array('data' => t('Description'), 'field' => 'description'),
- array('data' => $instances_present ? t('Operations') : '', 'colspan' => '2')
- );
- $query = db_select('actions')->extend('PagerDefault')->extend('TableSort');
- $result = $query
- ->fields('actions')
- ->limit(50)
- ->setHeader($header)
- ->execute();
-
- foreach ($result as $action) {
- $row[] = array(
- array('data' => $action->type),
- array('data' => $action->description),
- array('data' => $action->parameters ? l(t('configure'), "admin/settings/actions/configure/$action->aid") : ''),
- array('data' => $action->parameters ? l(t('delete'), "admin/settings/actions/delete/$action->aid") : '')
- );
- }
-
- if ($row) {
- $pager = theme('pager', NULL);
- if (!empty($pager)) {
- $row[] = array(array('data' => $pager, 'colspan' => '3'));
- }
- $output .= '
' . t('Actions available to Drupal:') . '
';
- $output .= theme('table', $header, $row);
- }
-
- if ($actions_map) {
- $output .= drupal_render(drupal_get_form('system_actions_manage_form', $options));
- }
-
- return $output;
-}
-
-/**
- * Define the form for the actions overview page.
- *
- * @see system_actions_manage_form_submit()
- * @ingroup forms
- * @param $form_state
- * An associative array containing the current state of the form; not used.
- * @param $options
- * An array of configurable actions.
- * @return
- * Form definition.
- */
-function system_actions_manage_form($form_state, $options = array()) {
- $form['parent'] = array(
- '#type' => 'fieldset',
- '#title' => t('Make a new advanced action available'),
- '#prefix' => '
',
- '#suffix' => '
',
- );
- $form['parent']['action'] = array(
- '#type' => 'select',
- '#default_value' => '',
- '#options' => $options,
- '#description' => '',
- );
- $form['parent']['buttons']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Create'),
- );
- return $form;
-}
-
-/**
- * Process system_actions_manage form submissions.
- */
-function system_actions_manage_form_submit($form, &$form_state) {
- if ($form_state['values']['action']) {
- $form_state['redirect'] = 'admin/settings/actions/configure/' . $form_state['values']['action'];
- }
-}
-
-/**
- * Menu callback. Create the form for configuration of a single action.
- *
- * We provide the "Description" field. The rest of the form
- * is provided by the action. We then provide the Save button.
- * Because we are combining unknown form elements with the action
- * configuration form, we use actions_ prefix on our elements.
- *
- * @see system_actions_configure_validate()
- * @see system_actions_configure_submit()
- * @param $action
- * md5 hash of action ID or an integer. If it's an md5 hash, we
- * are creating a new instance. If it's an integer, we're editing
- * an existing instance.
- * @return
- * Form definition.
- */
-function system_actions_configure($form_state, $action = NULL) {
- if ($action === NULL) {
- drupal_goto('admin/settings/actions');
- }
-
- $actions_map = actions_actions_map(actions_list());
- $edit = array();
-
- // Numeric action denotes saved instance of a configurable action;
- // else we are creating a new action instance.
- if (is_numeric($action)) {
- $aid = $action;
- // Load stored parameter values from database.
- $data = db_query("SELECT * FROM {actions} WHERE aid = :aid", array(':aid' => $aid))->fetch();
- $edit['actions_description'] = $data->description;
- $edit['actions_type'] = $data->type;
- $function = $data->callback;
- $action = md5($data->callback);
- $params = unserialize($data->parameters);
- if ($params) {
- foreach ($params as $name => $val) {
- $edit[$name] = $val;
- }
- }
- }
- else {
- $function = $actions_map[$action]['callback'];
- $edit['actions_description'] = $actions_map[$action]['description'];
- $edit['actions_type'] = $actions_map[$action]['type'];
- }
-
- $form['actions_description'] = array(
- '#type' => 'textfield',
- '#title' => t('Description'),
- '#default_value' => $edit['actions_description'],
- '#maxlength' => '255',
- '#description' => t('A unique description for this advanced action. This description will be displayed in the interface of modules that integrate with actions, such as Trigger module.'),
- '#weight' => -10
- );
- $action_form = $function . '_form';
- $form = array_merge($form, $action_form($edit));
- $form['actions_type'] = array(
- '#type' => 'value',
- '#value' => $edit['actions_type'],
- );
- $form['actions_action'] = array(
- '#type' => 'hidden',
- '#value' => $action,
- );
- // $aid is set when configuring an existing action instance.
- if (isset($aid)) {
- $form['actions_aid'] = array(
- '#type' => 'hidden',
- '#value' => $aid,
- );
- }
- $form['actions_configured'] = array(
- '#type' => 'hidden',
- '#value' => '1',
- );
- $form['buttons']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save'),
- '#weight' => 13
- );
-
- return $form;
-}
-
-/**
- * Validate system_actions_configure form submissions.
- */
-function system_actions_configure_validate($form, $form_state) {
- $function = actions_function_lookup($form_state['values']['actions_action']) . '_validate';
- // Hand off validation to the action.
- if (drupal_function_exists($function)) {
- $function($form, $form_state);
- }
-}
-
-/**
- * Process system_actions_configure form submissions.
- */
-function system_actions_configure_submit($form, &$form_state) {
- $function = actions_function_lookup($form_state['values']['actions_action']);
- $submit_function = $function . '_submit';
-
- // Action will return keyed array of values to store.
- $params = $submit_function($form, $form_state);
- $aid = isset($form_state['values']['actions_aid']) ? $form_state['values']['actions_aid'] : NULL;
-
- actions_save($function, $form_state['values']['actions_type'], $params, $form_state['values']['actions_description'], $aid);
- drupal_set_message(t('The action has been successfully saved.'));
-
- $form_state['redirect'] = 'admin/settings/actions/manage';
-}
-
-/**
- * Create the form for confirmation of deleting an action.
- *
- * @ingroup forms
- * @see system_actions_delete_form_submit()
- */
-function system_actions_delete_form($form_state, $action) {
-
- $form['aid'] = array(
- '#type' => 'hidden',
- '#value' => $action->aid,
- );
- return confirm_form($form,
- t('Are you sure you want to delete the action %action?', array('%action' => $action->description)),
- 'admin/settings/actions/manage',
- t('This cannot be undone.'),
- t('Delete'), t('Cancel')
- );
-}
-
-/**
- * Process system_actions_delete form submissions.
- *
- * Post-deletion operations for action deletion.
- */
-function system_actions_delete_form_submit($form, &$form_state) {
- $aid = $form_state['values']['aid'];
- $action = actions_load($aid);
- actions_delete($aid);
- $description = check_plain($action->description);
- watchdog('user', 'Deleted action %aid (%action)', array('%aid' => $aid, '%action' => $description));
- drupal_set_message(t('Action %action was deleted', array('%action' => $description)));
- $form_state['redirect'] = 'admin/settings/actions/manage';
-}
-
-/**
- * Post-deletion operations for deleting action orphans.
- *
- * @param $orphaned
- * An array of orphaned actions.
- */
-function system_action_delete_orphans_post($orphaned) {
- foreach ($orphaned as $callback) {
- drupal_set_message(t("Deleted orphaned action (%action).", array('%action' => $callback)));
- }
-}
-
-/**
- * Remove actions that are in the database but not supported by any enabled module.
- */
-function system_actions_remove_orphans() {
- actions_synchronize(TRUE);
- drupal_goto('admin/settings/actions/manage');
-}
-
-/**
- * Return a form definition so the Send email action can be configured.
- *
- * @see system_send_email_action_validate()
- * @see system_send_email_action_submit()
- * @param $context
- * Default values (if we are editing an existing action instance).
- * @return
- * Form definition.
- */
-function system_send_email_action_form($context) {
- // Set default values for form.
- if (!isset($context['recipient'])) {
- $context['recipient'] = '';
- }
- if (!isset($context['subject'])) {
- $context['subject'] = '';
- }
- if (!isset($context['message'])) {
- $context['message'] = '';
- }
-
- $form['recipient'] = array(
- '#type' => 'textfield',
- '#title' => t('Recipient'),
- '#default_value' => $context['recipient'],
- '#maxlength' => '254',
- '#description' => t('The email address to which the message should be sent OR enter %author if you would like to send an e-mail to the author of the original post.', array('%author' => '%author')),
- );
- $form['subject'] = array(
- '#type' => 'textfield',
- '#title' => t('Subject'),
- '#default_value' => $context['subject'],
- '#maxlength' => '254',
- '#description' => t('The subject of the message.'),
- );
- $form['message'] = array(
- '#type' => 'textarea',
- '#title' => t('Message'),
- '#default_value' => $context['message'],
- '#cols' => '80',
- '#rows' => '20',
- '#description' => t('The message that should be sent. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'),
- );
- return $form;
-}
-
-/**
- * Validate system_send_email_action form submissions.
- */
-function system_send_email_action_validate($form, $form_state) {
- $form_values = $form_state['values'];
- // Validate the configuration form.
- if (!valid_email_address($form_values['recipient']) && $form_values['recipient'] != '%author') {
- // We want the literal %author placeholder to be emphasized in the error message.
- form_set_error('recipient', t('Please enter a valid email address or %author.', array('%author' => '%author')));
- }
-}
-
-/**
- * Process system_send_email_action form submissions.
- */
-function system_send_email_action_submit($form, $form_state) {
- $form_values = $form_state['values'];
- // Process the HTML form to store configuration. The keyed array that
- // we return will be serialized to the database.
- $params = array(
- 'recipient' => $form_values['recipient'],
- 'subject' => $form_values['subject'],
- 'message' => $form_values['message'],
- );
- return $params;
-}
-
-/**
- * Implementation of a configurable Drupal action. Sends an email.
- */
-function system_send_email_action($object, $context) {
- global $user;
-
- switch ($context['hook']) {
- case 'node':
- // Because this is not an action of type 'node' the node
- // will not be passed as $object, but it will still be available
- // in $context.
- $node = $context['node'];
- break;
- // The comment hook provides nid, in $context.
- case 'comment':
- $comment = $context['comment'];
- $node = node_load($comment->nid);
- break;
- case 'user':
- // Because this is not an action of type 'user' the user
- // object is not passed as $object, but it will still be available
- // in $context.
- $account = $context['account'];
- if (isset($context['node'])) {
- $node = $context['node'];
- }
- elseif ($context['recipient'] == '%author') {
- // If we don't have a node, we don't have a node author.
- watchdog('error', 'Cannot use %author token in this context.');
- return;
- }
- break;
- default:
- // We are being called directly.
- $node = $object;
- }
-
- $recipient = $context['recipient'];
-
- if (isset($node)) {
- if (!isset($account)) {
- $account = user_load($node->uid);
- }
- if ($recipient == '%author') {
- $recipient = $account->mail;
- }
- }
-
- if (!isset($account)) {
- $account = $user;
-
- }
- $language = user_preferred_language($account);
- $params = array('account' => $account, 'object' => $object, 'context' => $context);
- if (isset($node)) {
- $params['node'] = $node;
- }
-
- if (drupal_mail('system', 'action_send_email', $recipient, $language, $params)) {
- watchdog('action', 'Sent email to %recipient', array('%recipient' => $recipient));
- }
- else {
- watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipient));
- }
-}
-
-/**
- * Implementation of hook_mail().
- */
-function system_mail($key, &$message, $params) {
- $account = $params['account'];
- $context = $params['context'];
- $variables = array(
- '%site_name' => variable_get('site_name', 'Drupal'),
- '%username' => $account->name,
- );
- if ($context['hook'] == 'taxonomy') {
- $object = $params['object'];
- $vocabulary = taxonomy_vocabulary_load($object->vid);
- $variables += array(
- '%term_name' => $object->name,
- '%term_description' => $object->description,
- '%term_id' => $object->tid,
- '%vocabulary_name' => $vocabulary->name,
- '%vocabulary_description' => $vocabulary->description,
- '%vocabulary_id' => $vocabulary->vid,
- );
- }
-
- // Node-based variable translation is only available if we have a node.
- if (isset($params['node'])) {
- $node = $params['node'];
- $variables += array(
- '%uid' => $node->uid,
- '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
- '%node_type' => node_get_types('name', $node),
- '%title' => $node->title,
- '%teaser' => $node->teaser,
- '%body' => $node->body,
- );
- }
- $subject = strtr($context['subject'], $variables);
- $body = strtr($context['message'], $variables);
- $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
- $message['body'][] = drupal_html_to_text($body);
-}
-
-function system_message_action_form($context) {
- $form['message'] = array(
- '#type' => 'textarea',
- '#title' => t('Message'),
- '#default_value' => isset($context['message']) ? $context['message'] : '',
- '#required' => TRUE,
- '#rows' => '8',
- '#description' => t('The message to be displayed to the current user. You may include the following variables: %site_name, %username, %node_url, %node_type, %title, %teaser, %body. Not all variables will be available in all contexts.'),
- );
- return $form;
-}
-
-function system_message_action_submit($form, $form_state) {
- return array('message' => $form_state['values']['message']);
-}
-
-/**
- * A configurable Drupal action. Sends a message to the current user's screen.
- */
-function system_message_action(&$object, $context = array()) {
- global $user;
- $variables = array(
- '%site_name' => variable_get('site_name', 'Drupal'),
- '%username' => $user->name ? $user->name : variable_get('anonymous', t('Anonymous')),
- );
-
- // This action can be called in any context, but if placeholders
- // are used a node object must be present to be the source
- // of substituted text.
- switch ($context['hook']) {
- case 'node':
- // Because this is not an action of type 'node' the node
- // will not be passed as $object, but it will still be available
- // in $context.
- $node = $context['node'];
- break;
- // The comment hook also provides the node, in context.
- case 'comment':
- $comment = $context['comment'];
- $node = node_load($comment->nid);
- break;
- case 'taxonomy':
- $vocabulary = taxonomy_vocabulary_load($object->vid);
- $variables = array_merge($variables, array(
- '%term_name' => $object->name,
- '%term_description' => $object->description,
- '%term_id' => $object->tid,
- '%vocabulary_name' => $vocabulary->name,
- '%vocabulary_description' => $vocabulary->description,
- '%vocabulary_id' => $vocabulary->vid,
- )
- );
- break;
- default:
- // We are being called directly.
- $node = $object;
- }
-
- if (isset($node) && is_object($node)) {
- $variables = array_merge($variables, array(
- '%uid' => $node->uid,
- '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
- '%node_type' => check_plain(node_get_types('name', $node)),
- '%title' => filter_xss($node->title),
- '%teaser' => filter_xss($node->teaser),
- '%body' => filter_xss($node->body),
- )
- );
- }
- $context['message'] = strtr($context['message'], $variables);
- drupal_set_message($context['message']);
-}
-
-/**
- * Implementation of a configurable Drupal action. Redirect user to a URL.
- */
-function system_goto_action_form($context) {
- $form['url'] = array(
- '#type' => 'textfield',
- '#title' => t('URL'),
- '#description' => t('The URL to which the user should be redirected. This can be an internal URL like node/1234 or an external URL like http://drupal.org.'),
- '#default_value' => isset($context['url']) ? $context['url'] : '',
- '#required' => TRUE,
- );
- return $form;
-}
-
-function system_goto_action_submit($form, $form_state) {
- return array(
- 'url' => $form_state['values']['url']
- );
-}
-
-function system_goto_action($object, $context) {
- drupal_goto($context['url']);
-}
-
-/**
- * Implementation of a Drupal action.
- * Blocks the user's IP address.
- */
-function system_block_ip_action() {
- $ip = ip_address();
- db_insert('blocked_ips')
- ->fields(array('ip' => $ip))
- ->execute();
- watchdog('action', 'Banned IP address %ip', array('%ip' => $ip));
-}
-
-/**
* Generate an array of time zones and their local time&date.
*
* @param $blank
Index: modules/system/system.registry.inc
===================================================================
RCS file: modules/system/system.registry.inc
diff -N modules/system/system.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.registry.inc 21 May 2009 23:14:00 -0000
@@ -0,0 +1,381 @@
+ 'File download',
+ 'page callback' => 'file_download',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+ $items['system/ahah'] = array(
+ 'title' => 'AHAH callback',
+ 'page callback' => 'form_ahah_callback',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+ $items['system/timezone'] = array(
+ 'title' => 'Time zone',
+ 'page callback' => 'system_timezone',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin'] = array(
+ 'title' => 'Administer',
+ 'access arguments' => array('access administration pages'),
+ 'page callback' => 'system_main_admin_page',
+ 'weight' => 9,
+ 'menu_name' => 'management',
+ );
+ $items['admin/compact'] = array(
+ 'title' => 'Compact mode',
+ 'page callback' => 'system_admin_compact_page',
+ 'access arguments' => array('access administration pages'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/by-task'] = array(
+ 'title' => 'By task',
+ 'page callback' => 'system_main_admin_page',
+ 'access arguments' => array('access administration pages'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $items['admin/by-module'] = array(
+ 'title' => 'By module',
+ 'page callback' => 'system_admin_by_module',
+ 'access arguments' => array('access administration pages'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ );
+ $items['admin/content'] = array(
+ 'title' => 'Content management',
+ 'description' => "Manage your site's content.",
+ 'position' => 'left',
+ 'weight' => -10,
+ 'page callback' => 'system_admin_menu_block_page',
+ 'access arguments' => array('access administration pages'),
+ );
+
+ // menu items that are basically just menu blocks
+ $items['admin/settings'] = array(
+ 'title' => 'Site configuration',
+ 'description' => 'Configure site settings.',
+ 'position' => 'right',
+ 'weight' => -5,
+ 'page callback' => 'system_settings_overview',
+ 'access arguments' => array('access administration pages'),
+ );
+ $items['admin/build'] = array(
+ 'title' => 'Site building',
+ 'description' => 'Control how your site looks and feels.',
+ 'position' => 'right',
+ 'weight' => -10,
+ 'page callback' => 'system_admin_menu_block_page',
+ 'access arguments' => array('access administration pages'),
+ );
+ // Themes:
+ $items['admin/build/themes'] = array(
+ 'title' => 'Themes',
+ 'description' => 'Change which theme your site uses or allows users to set.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_themes_form'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/build/themes/select'] = array(
+ 'title' => 'List',
+ 'description' => 'Select the default theme for your site.',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -1,
+ );
+ $items['admin/build/themes/settings'] = array(
+ 'title' => 'Configure',
+ 'page arguments' => array('system_theme_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ // Theme configuration subtabs
+ $items['admin/build/themes/settings/global'] = array(
+ 'title' => 'Global settings',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -1,
+ );
+
+ foreach (list_themes() as $theme) {
+ $items['admin/build/themes/settings/' . $theme->name] = array(
+ 'title' => $theme->info['name'],
+ 'page arguments' => array('system_theme_settings', $theme->name),
+ 'type' => MENU_LOCAL_TASK,
+ 'access callback' => '_system_themes_access',
+ 'access arguments' => array($theme),
+ );
+ }
+
+ // Modules:
+ $items['admin/build/modules'] = array(
+ 'title' => 'Modules',
+ 'description' => 'Enable or disable add-on modules for your site.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_modules'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/build/modules/list'] = array(
+ 'title' => 'List',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $items['admin/build/modules/list/confirm'] = array(
+ 'title' => 'List',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/build/modules/uninstall'] = array(
+ 'title' => 'Uninstall',
+ 'page arguments' => array('system_modules_uninstall'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/build/modules/uninstall/confirm'] = array(
+ 'title' => 'Uninstall',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ // Actions:
+ $items['admin/settings/actions'] = array(
+ 'title' => 'Actions',
+ 'description' => 'Manage the actions defined for your site.',
+ 'access arguments' => array('administer actions'),
+ 'page callback' => 'system_actions_manage'
+ );
+ $items['admin/settings/actions/manage'] = array(
+ 'title' => 'Manage actions',
+ 'description' => 'Manage the actions defined for your site.',
+ 'page callback' => 'system_actions_manage',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -2,
+ );
+ $items['admin/settings/actions/configure'] = array(
+ 'title' => 'Configure an advanced action',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_actions_configure'),
+ 'access arguments' => array('administer actions'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/settings/actions/delete/%actions'] = array(
+ 'title' => 'Delete action',
+ 'description' => 'Delete an action.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_actions_delete_form', 4),
+ 'access arguments' => array('administer actions'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/settings/actions/orphan'] = array(
+ 'title' => 'Remove orphans',
+ 'page callback' => 'system_actions_remove_orphans',
+ 'access arguments' => array('administer actions'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ // IP address blocking.
+ $items['admin/settings/ip-blocking'] = array(
+ 'title' => 'IP address blocking',
+ 'description' => 'Manage blocked IP addresses.',
+ 'page callback' => 'system_ip_blocking',
+ 'access arguments' => array('block IP addresses'),
+ );
+ $items['admin/settings/ip-blocking/%'] = array(
+ 'title' => 'IP address blocking',
+ 'description' => 'Manage blocked IP addresses.',
+ 'page callback' => 'system_ip_blocking',
+ 'access arguments' => array('block IP addresses'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/settings/ip-blocking/delete/%blocked_ip'] = array(
+ 'title' => 'Delete IP address',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_ip_blocking_delete', 4),
+ 'access arguments' => array('block IP addresses'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ // Settings:
+ $items['admin/settings/site-information'] = array(
+ 'title' => 'Site information',
+ 'description' => 'Change basic site information, such as the site name, slogan, e-mail address, mission, front page and more.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_site_information_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/logging'] = array(
+ 'title' => 'Logging and errors',
+ 'description' => "Settings for logging and alerts modules. Various modules can route Drupal's system events to different destinations, such as syslog, database, email, etc.",
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_logging_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/logging/settings'] = array(
+ 'title' => 'Settings',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -1,
+ );
+ $items['admin/settings/performance'] = array(
+ 'title' => 'Performance',
+ 'description' => 'Enable or disable page caching for anonymous users and set CSS and JS bandwidth optimization options.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_performance_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/file-system'] = array(
+ 'title' => 'File system',
+ 'description' => 'Tell Drupal where to store uploaded files and how they are accessed.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_file_system_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/image-toolkit'] = array(
+ 'title' => 'Image toolkit',
+ 'description' => 'Choose which image toolkit to use if you have installed optional toolkits.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_image_toolkit_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/content/rss-publishing'] = array(
+ 'title' => 'RSS publishing',
+ 'description' => 'Configure the site description, the number of items per feed and whether feeds should be titles/teasers/full-text.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_rss_feeds_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/regional-settings'] = array(
+ 'title' => 'Regional settings',
+ 'description' => "Settings for how Drupal displays date and time, as well as the system's default time zone.",
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_regional_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/regional-settings/lookup'] = array(
+ 'title' => 'Date and time lookup',
+ 'type' => MENU_CALLBACK,
+ 'page callback' => 'system_date_time_lookup',
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/maintenance-mode'] = array(
+ 'title' => 'Maintenance mode',
+ 'description' => 'Take the site offline for maintenance or bring it back online.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_site_maintenance_mode'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/clean-urls'] = array(
+ 'title' => 'Clean URLs',
+ 'description' => 'Enable or disable clean URLs for your site.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_clean_url_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/settings/clean-urls/check'] = array(
+ 'title' => 'Clean URL check',
+ 'page callback' => 'drupal_json',
+ 'page arguments' => array(array('status' => TRUE)),
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+
+ // Reports:
+ $items['admin/reports'] = array(
+ 'title' => 'Reports',
+ 'description' => 'View reports from system logs and other status information.',
+ 'page callback' => 'system_admin_menu_block_page',
+ 'access arguments' => array('access site reports'),
+ 'weight' => 5,
+ 'position' => 'left',
+ );
+ $items['admin/reports/status'] = array(
+ 'title' => 'Status report',
+ 'description' => "Get a status report about your site's operation and any detected problems.",
+ 'page callback' => 'system_status',
+ 'weight' => 10,
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/reports/status/run-cron'] = array(
+ 'title' => 'Run cron',
+ 'page callback' => 'system_run_cron',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/reports/status/php'] = array(
+ 'title' => 'PHP',
+ 'page callback' => 'system_php',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/reports/status/sql'] = array(
+ 'title' => 'SQL',
+ 'page callback' => 'system_sql',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ );
+ // Default page for batch operations
+ $items['batch'] = array(
+ 'page callback' => 'system_batch_page',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function system_theme() {
+ return array_merge(drupal_common_theme(), array(
+ 'system_theme_select_form' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'system_themes_form' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'system_modules_fieldset' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'system_modules_incompatible' => array(
+ 'arguments' => array('message' => NULL),
+ ),
+ 'system_modules_uninstall' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'status_report' => array(
+ 'arguments' => array('requirements' => NULL),
+ ),
+ 'admin_page' => array(
+ 'arguments' => array('blocks' => NULL),
+ ),
+ 'admin_block' => array(
+ 'arguments' => array('block' => NULL),
+ ),
+ 'admin_block_content' => array(
+ 'arguments' => array('content' => NULL),
+ ),
+ 'system_admin_by_module' => array(
+ 'arguments' => array('menu_items' => NULL),
+ ),
+ 'system_powered_by' => array(
+ 'arguments' => array('image_path' => NULL),
+ ),
+ 'meta_generator_html' => array(
+ 'arguments' => array('version' => NULL),
+ ),
+ 'meta_generator_header' => array(
+ 'arguments' => array('version' => NULL),
+ ),
+ 'system_compact_link' => array(),
+ ));
+}
+
Index: modules/system/system.user.inc
===================================================================
RCS file: modules/system/system.user.inc
diff -N modules/system/system.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.user.inc 21 May 2009 23:14:15 -0000
@@ -0,0 +1,111 @@
+ array(
+ 'title' => t('Administer site configuration'),
+ 'description' => t('Configure site-wide settings such as module or theme administration settings.'),
+ ),
+ 'administer actions' => array(
+ 'title' => t('Administer actions'),
+ 'description' => t('Manage the actions defined for your site.'),
+ ),
+ 'administer files' => array(
+ 'title' => t('Administer files'),
+ 'description' => t('Manage user-uploaded files.'),
+ ),
+ 'access administration pages' => array(
+ 'title' => t('Access administration pages'),
+ 'description' => t('View the administration panel and browse the help system.'),
+ ),
+ 'access site reports' => array(
+ 'title' => t('Access site reports'),
+ 'description' => t('View reports from system logs and other status information.'),
+ ),
+ 'select different theme' => array(
+ 'title' => t('Select different theme'),
+ 'description' => t('Select a theme other than the default theme set by the site administrator.'),
+ ),
+ 'block IP addresses' => array(
+ 'title' => t('Block IP addresses'),
+ 'description' => t('Block IP addresses from accessing your site.'),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_user_form().
+ */
+function system_user_form(&$edit, &$user, $category = NULL) {
+ if ($category == 'account') {
+ $form['theme_select'] = system_theme_select_form(t('Selecting a different theme will change the look and feel of the site.'), isset($edit['theme']) ? $edit['theme'] : NULL, 2);
+ if (variable_get('configurable_timezones', 1)) {
+ system_user_timezone($edit, $form);
+ }
+ return $form;
+ }
+}
+
+/**
+ * Implementation of hook_user_register().
+ */
+function system_user_register(&$edit, &$user, $category = NULL) {
+ if (variable_get('configurable_timezones', 1)) {
+ $form = array();
+ if (variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) == DRUPAL_USER_TIMEZONE_SELECT) {
+ system_user_timezone($edit, $form);
+ }
+ else {
+ $form['timezone'] = array(
+ '#type' => 'hidden',
+ '#value' => variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) ? '' : variable_get('date_default_timezone', ''),
+ );
+ }
+ return $form;
+ }
+}
+
+/**
+ * Implementation of hook_user_login().
+ */
+function system_user_login(&$edit, &$user, $category = NULL) {
+ // If the user has a NULL time zone, notify them to set a time zone.
+ if (!$user->timezone && variable_get('configurable_timezones', 1) && variable_get('empty_timezone_message', 0)) {
+ drupal_set_message(t('Please configure your account time zone setting.', array('@user-edit' => url("user/$user->uid/edit", array('query' => drupal_get_destination(), 'fragment' => 'edit-timezone')))));
+ }
+}
+
+/**
+ * Add the time zone field to the user edit and register forms.
+ */
+function system_user_timezone(&$edit, &$form) {
+ global $user;
+ $form['timezone'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Locale settings'),
+ '#weight' => 6,
+ '#collapsible' => TRUE,
+ );
+ $form['timezone']['timezone'] = array(
+ '#type' => 'select',
+ '#title' => t('Time zone'),
+ '#default_value' => $edit['timezone'] ? $edit['timezone'] : ($edit['uid'] == $user->uid ? variable_get('date_default_timezone', '') : ''),
+ '#options' => system_time_zones(($edit['uid'] != $user->uid)),
+ '#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
+ );
+ if (!$edit['timezone'] && $edit['uid'] == $user->uid) {
+ $form['timezone']['#description'] = t('Your time zone setting will be automatically detected if possible. Please confirm the selection and click save.');
+ $form['timezone']['timezone']['#attributes'] = array('class' => 'timezone-detect');
+ drupal_add_js('misc/timezone.js');
+ }
+}
+
Index: modules/taxonomy/taxonomy.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.info,v
retrieving revision 1.8
diff -u -p -r1.8 taxonomy.info
--- modules/taxonomy/taxonomy.info 11 Oct 2008 02:33:06 -0000 1.8
+++ modules/taxonomy/taxonomy.info 21 May 2009 23:14:37 -0000
@@ -8,3 +8,7 @@ files[] = taxonomy.module
files[] = taxonomy.admin.inc
files[] = taxonomy.pages.inc
files[] = taxonomy.install
+files[] = taxonomy.registry.inc
+files[] = taxonomy.user.inc
+files[] = taxonomy.node.inc
+files[] = taxonomy.search.inc
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.473
diff -u -p -r1.473 taxonomy.module
--- modules/taxonomy/taxonomy.module 19 May 2009 19:01:51 -0000 1.473
+++ modules/taxonomy/taxonomy.module 21 May 2009 23:14:37 -0000
@@ -7,35 +7,6 @@
*/
/**
- * Implementation of hook_perm().
- */
-function taxonomy_perm() {
- return array(
- 'administer taxonomy' => array(
- 'title' => t('Administer taxonomy'),
- 'description' => t('Manage taxonomy vocabularies and terms.'),
- ),
- );
-}
-
-/**
- * Implementation of hook_theme().
- */
-function taxonomy_theme() {
- return array(
- 'taxonomy_term_select' => array(
- 'arguments' => array('element' => NULL),
- ),
- 'taxonomy_overview_vocabularies' => array(
- 'arguments' => array('form' => array()),
- ),
- 'taxonomy_overview_terms' => array(
- 'arguments' => array('form' => array()),
- ),
- );
-}
-
-/**
* An implementation of hook_node_view().
*/
function taxonomy_node_view($node) {
@@ -112,97 +83,6 @@ function taxonomy_term_path($term) {
}
/**
- * Implementation of hook_menu().
- */
-function taxonomy_menu() {
- $items['admin/content/taxonomy'] = array(
- 'title' => 'Taxonomy',
- 'description' => 'Manage tagging, categorization, and classification of your content.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_overview_vocabularies'),
- 'access arguments' => array('administer taxonomy'),
- );
-
- $items['admin/content/taxonomy/list'] = array(
- 'title' => 'List',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
-
- $items['admin/content/taxonomy/add'] = array(
- 'title' => 'Add vocabulary',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_form_vocabulary'),
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items['taxonomy/term/%taxonomy_terms'] = array(
- 'title' => 'Taxonomy term',
- 'page callback' => 'taxonomy_term_page',
- 'page arguments' => array(2),
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
-
- $items['taxonomy/term/%taxonomy_terms/view'] = array(
- 'title' => 'View',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
-
- $items['taxonomy/term/%taxonomy_term/edit'] = array(
- 'title' => 'Edit term',
- 'page callback' => 'taxonomy_term_edit',
- 'page arguments' => array(2),
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 10,
- );
-
- $items['taxonomy/autocomplete'] = array(
- 'title' => 'Autocomplete taxonomy',
- 'page callback' => 'taxonomy_autocomplete',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
-
- $items['admin/content/taxonomy/%taxonomy_vocabulary'] = array(
- 'title' => 'Vocabulary', // this is replaced by callback
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_form_vocabulary', 3),
- 'title callback' => 'taxonomy_admin_vocabulary_title_callback',
- 'title arguments' => array(3),
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_CALLBACK,
- );
-
- $items['admin/content/taxonomy/%taxonomy_vocabulary/edit'] = array(
- 'title' => 'Edit vocabulary',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -20,
- );
-
- $items['admin/content/taxonomy/%taxonomy_vocabulary/list'] = array(
- 'title' => 'List terms',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_overview_terms', 3),
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => -10,
- );
-
- $items['admin/content/taxonomy/%taxonomy_vocabulary/add'] = array(
- 'title' => 'Add term',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_form_term', 3),
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_LOCAL_TASK,
- );
-
- return $items;
-}
-
-/**
* Return the vocabulary name given the vocabulary object.
*/
function taxonomy_admin_vocabulary_title_callback($vocabulary) {
@@ -859,26 +739,6 @@ function taxonomy_node_save($node, $term
}
/**
- * Implementation of hook_node_type().
- */
-function taxonomy_node_type($op, $info) {
- if ($op == 'update' && !empty($info->old_type) && $info->type != $info->old_type) {
- db_update('taxonomy_vocabulary_node_type')
- ->fields(array(
- 'type' => $info->type,
- ))
- ->condition('type', $info->old_type)
- ->execute();
- }
- elseif ($op == 'delete') {
- db_delete('taxonomy_vocabulary_node_type')
- ->condition('type', $info->type)
- ->execute();
- }
- drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
* Find all term objects related to a given term ID.
*/
function taxonomy_get_related($tid, $key = 'tid') {
@@ -1585,82 +1445,6 @@ function taxonomy_node_load($nodes) {
}
/**
- * Implementation of hook_node_insert().
- */
-function taxonomy_node_insert($node) {
- if (!empty($node->taxonomy)) {
- taxonomy_node_save($node, $node->taxonomy);
- }
-}
-
-/**
- * Implementation of hook_node_update().
- */
-function taxonomy_node_update($node) {
- if (!empty($node->taxonomy)) {
- taxonomy_node_save($node, $node->taxonomy);
- }
-}
-
-/**
- * Implementation of hook_node_delete().
- *
- * Remove associations of a node to its terms.
- */
-function taxonomy_node_delete($node) {
- db_delete('taxonomy_term_node')
- ->condition('nid', $node->nid)
- ->execute();
- drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
- * Implementation of hook_node_delete_revision().
- *
- * Remove associations of a node to its terms.
- */
-function taxonomy_node_delete_revision($node) {
- db_delete('taxonomy_term_node')
- ->condition('nid', $node->vid)
- ->execute();
- drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
- * Implementation of hook_node_validate().
- *
- * Make sure incoming vids are free tagging enabled.
- */
-function taxonomy_node_validate($node, $form) {
- if (!empty($node->taxonomy)) {
- $terms = $node->taxonomy;
- if (!empty($terms['tags'])) {
- foreach ($terms['tags'] as $vid => $vid_value) {
- $vocabulary = taxonomy_vocabulary_load($vid);
- if (empty($vocabulary->tags)) {
- // see form_get_error $key = implode('][', $element['#parents']);
- // on why this is the key
- form_set_error("taxonomy][tags][$vid", t('The %name vocabulary can not be modified in this way.', array('%name' => $vocabulary->name)));
- }
- }
- }
- }
-}
-
-/**
- * Implementation of hook_node_update_index().
- */
-function taxonomy_node_update_index($node) {
- $output = array();
- foreach ($node->taxonomy as $term) {
- $output[] = $term->name;
- }
- if (count($output)) {
- return '(' . implode(', ', $output) . ')';
- }
-}
-
-/**
* Parses a comma or plus separated string of term IDs.
*
* @param $str_tids
Index: modules/taxonomy/taxonomy.node.inc
===================================================================
RCS file: modules/taxonomy/taxonomy.node.inc
diff -N modules/taxonomy/taxonomy.node.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/taxonomy/taxonomy.node.inc 21 May 2009 23:14:27 -0000
@@ -0,0 +1,91 @@
+old_type) && $info->type != $info->old_type) {
+ db_update('taxonomy_vocabulary_node_type')
+ ->fields(array(
+ 'type' => $info->type,
+ ))
+ ->condition('type', $info->old_type)
+ ->execute();
+ }
+ elseif ($op == 'delete') {
+ db_delete('taxonomy_vocabulary_node_type')
+ ->condition('type', $info->type)
+ ->execute();
+ }
+ drupal_static_reset('taxonomy_term_count_nodes');
+}
+
+/**
+ * Implementation of hook_node_insert().
+ */
+function taxonomy_node_insert($node) {
+ if (!empty($node->taxonomy)) {
+ taxonomy_node_save($node, $node->taxonomy);
+ }
+}
+
+/**
+ * Implementation of hook_node_update().
+ */
+function taxonomy_node_update($node) {
+ if (!empty($node->taxonomy)) {
+ taxonomy_node_save($node, $node->taxonomy);
+ }
+}
+
+/**
+ * Implementation of hook_node_delete().
+ *
+ * Remove associations of a node to its terms.
+ */
+function taxonomy_node_delete($node) {
+ db_delete('taxonomy_term_node')
+ ->condition('nid', $node->nid)
+ ->execute();
+ drupal_static_reset('taxonomy_term_count_nodes');
+}
+
+/**
+ * Implementation of hook_node_delete_revision().
+ *
+ * Remove associations of a node to its terms.
+ */
+function taxonomy_node_delete_revision($node) {
+ db_delete('taxonomy_term_node')
+ ->condition('nid', $node->vid)
+ ->execute();
+ drupal_static_reset('taxonomy_term_count_nodes');
+}
+
+/**
+ * Implementation of hook_node_validate().
+ *
+ * Make sure incoming vids are free tagging enabled.
+ */
+function taxonomy_node_validate($node, $form) {
+ if (!empty($node->taxonomy)) {
+ $terms = $node->taxonomy;
+ if (!empty($terms['tags'])) {
+ foreach ($terms['tags'] as $vid => $vid_value) {
+ $vocabulary = taxonomy_vocabulary_load($vid);
+ if (empty($vocabulary->tags)) {
+ // see form_get_error $key = implode('][', $element['#parents']);
+ // on why this is the key
+ form_set_error("taxonomy][tags][$vid", t('The %name vocabulary can not be modified in this way.', array('%name' => $vocabulary->name)));
+ }
+ }
+ }
+ }
+}
+
Index: modules/taxonomy/taxonomy.registry.inc
===================================================================
RCS file: modules/taxonomy/taxonomy.registry.inc
diff -N modules/taxonomy/taxonomy.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/taxonomy/taxonomy.registry.inc 21 May 2009 23:14:00 -0000
@@ -0,0 +1,116 @@
+ 'Taxonomy',
+ 'description' => 'Manage tagging, categorization, and classification of your content.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('taxonomy_overview_vocabularies'),
+ 'access arguments' => array('administer taxonomy'),
+ );
+
+ $items['admin/content/taxonomy/list'] = array(
+ 'title' => 'List',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -10,
+ );
+
+ $items['admin/content/taxonomy/add'] = array(
+ 'title' => 'Add vocabulary',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('taxonomy_form_vocabulary'),
+ 'access arguments' => array('administer taxonomy'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ $items['taxonomy/term/%taxonomy_terms'] = array(
+ 'title' => 'Taxonomy term',
+ 'page callback' => 'taxonomy_term_page',
+ 'page arguments' => array(2),
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['taxonomy/term/%taxonomy_terms/view'] = array(
+ 'title' => 'View',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+
+ $items['taxonomy/term/%taxonomy_term/edit'] = array(
+ 'title' => 'Edit term',
+ 'page callback' => 'taxonomy_term_edit',
+ 'page arguments' => array(2),
+ 'access arguments' => array('administer taxonomy'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 10,
+ );
+
+ $items['taxonomy/autocomplete'] = array(
+ 'title' => 'Autocomplete taxonomy',
+ 'page callback' => 'taxonomy_autocomplete',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['admin/content/taxonomy/%taxonomy_vocabulary'] = array(
+ 'title' => 'Vocabulary', // this is replaced by callback
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('taxonomy_form_vocabulary', 3),
+ 'title callback' => 'taxonomy_admin_vocabulary_title_callback',
+ 'title arguments' => array(3),
+ 'access arguments' => array('administer taxonomy'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['admin/content/taxonomy/%taxonomy_vocabulary/edit'] = array(
+ 'title' => 'Edit vocabulary',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -20,
+ );
+
+ $items['admin/content/taxonomy/%taxonomy_vocabulary/list'] = array(
+ 'title' => 'List terms',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('taxonomy_overview_terms', 3),
+ 'access arguments' => array('administer taxonomy'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => -10,
+ );
+
+ $items['admin/content/taxonomy/%taxonomy_vocabulary/add'] = array(
+ 'title' => 'Add term',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('taxonomy_form_term', 3),
+ 'access arguments' => array('administer taxonomy'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function taxonomy_theme() {
+ return array(
+ 'taxonomy_term_select' => array(
+ 'arguments' => array('element' => NULL),
+ ),
+ 'taxonomy_overview_vocabularies' => array(
+ 'arguments' => array('form' => array()),
+ ),
+ 'taxonomy_overview_terms' => array(
+ 'arguments' => array('form' => array()),
+ ),
+ );
+}
+
Index: modules/taxonomy/taxonomy.search.inc
===================================================================
RCS file: modules/taxonomy/taxonomy.search.inc
diff -N modules/taxonomy/taxonomy.search.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/taxonomy/taxonomy.search.inc 21 May 2009 23:14:37 -0000
@@ -0,0 +1,21 @@
+taxonomy as $term) {
+ $output[] = $term->name;
+ }
+ if (count($output)) {
+ return '(' . implode(', ', $output) . ')';
+ }
+}
+
Index: modules/taxonomy/taxonomy.user.inc
===================================================================
RCS file: modules/taxonomy/taxonomy.user.inc
diff -N modules/taxonomy/taxonomy.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/taxonomy/taxonomy.user.inc 21 May 2009 23:14:15 -0000
@@ -0,0 +1,20 @@
+ array(
+ 'title' => t('Administer taxonomy'),
+ 'description' => t('Manage taxonomy vocabularies and terms.'),
+ ),
+ );
+}
+
Index: modules/tracker/tracker.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/tracker/tracker.info,v
retrieving revision 1.8
diff -u -p -r1.8 tracker.info
--- modules/tracker/tracker.info 11 Oct 2008 02:33:07 -0000 1.8
+++ modules/tracker/tracker.info 21 May 2009 23:14:00 -0000
@@ -7,3 +7,4 @@ version = VERSION
core = 7.x
files[] = tracker.module
files[] = tracker.pages.inc
+files[] = tracker.registry.inc
Index: modules/tracker/tracker.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/tracker/tracker.module,v
retrieving revision 1.157
diff -u -p -r1.157 tracker.module
--- modules/tracker/tracker.module 6 May 2008 12:18:51 -0000 1.157
+++ modules/tracker/tracker.module 21 May 2009 23:14:00 -0000
@@ -20,43 +20,6 @@ function tracker_help($path, $arg) {
}
/**
- * Implementation of hook_menu().
- */
-function tracker_menu() {
- $items['tracker'] = array(
- 'title' => 'Recent posts',
- 'page callback' => 'tracker_page',
- 'access arguments' => array('access content'),
- 'weight' => 1,
- );
- $items['tracker/all'] = array(
- 'title' => 'All recent posts',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- $items['tracker/%user_uid_optional'] = array(
- 'title' => 'My recent posts',
- 'access callback' => '_tracker_myrecent_access',
- 'access arguments' => array(1),
- 'page arguments' => array(1),
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items['user/%user/track'] = array(
- 'title' => 'Track',
- 'page callback' => 'tracker_page',
- 'page arguments' => array(1, TRUE),
- 'access callback' => '_tracker_user_access',
- 'access arguments' => array(1),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['user/%user/track/posts'] = array(
- 'title' => 'Track posts',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
- return $items;
-}
-
-/**
* Access callback for tracker/%user_uid_optional
*/
function _tracker_myrecent_access($account) {
Index: modules/tracker/tracker.registry.inc
===================================================================
RCS file: modules/tracker/tracker.registry.inc
diff -N modules/tracker/tracker.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/tracker/tracker.registry.inc 21 May 2009 23:14:00 -0000
@@ -0,0 +1,45 @@
+ 'Recent posts',
+ 'page callback' => 'tracker_page',
+ 'access arguments' => array('access content'),
+ 'weight' => 1,
+ );
+ $items['tracker/all'] = array(
+ 'title' => 'All recent posts',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ $items['tracker/%user_uid_optional'] = array(
+ 'title' => 'My recent posts',
+ 'access callback' => '_tracker_myrecent_access',
+ 'access arguments' => array(1),
+ 'page arguments' => array(1),
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ $items['user/%user/track'] = array(
+ 'title' => 'Track',
+ 'page callback' => 'tracker_page',
+ 'page arguments' => array(1, TRUE),
+ 'access callback' => '_tracker_user_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['user/%user/track/posts'] = array(
+ 'title' => 'Track posts',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+ return $items;
+}
+
Index: modules/translation/translation.form.inc
===================================================================
RCS file: modules/translation/translation.form.inc
diff -N modules/translation/translation.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/translation/translation.form.inc 21 May 2009 23:14:46 -0000
@@ -0,0 +1,18 @@
+enabled languages. You can also turn on translation for this content type, which lets you have content translated to any of the enabled languages. If disabled, new posts are saved with the default language. Existing content will not be affected by changing this option.', array('!languages' => url('admin/settings/language')));
+}
+
Index: modules/translation/translation.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/translation/translation.info,v
retrieving revision 1.4
diff -u -p -r1.4 translation.info
--- modules/translation/translation.info 11 Oct 2008 02:33:09 -0000 1.4
+++ modules/translation/translation.info 21 May 2009 23:14:46 -0000
@@ -7,3 +7,7 @@ version = VERSION
core = 7.x
files[] = translation.module
files[] = translation.pages.inc
+files[] = translation.registry.inc
+files[] = translation.user.inc
+files[] = translation.node.inc
+files[] = translation.form.inc
Index: modules/translation/translation.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/translation/translation.module,v
retrieving revision 1.45
diff -u -p -r1.45 translation.module
--- modules/translation/translation.module 18 May 2009 09:45:01 -0000 1.45
+++ modules/translation/translation.module 21 May 2009 23:14:46 -0000
@@ -51,23 +51,6 @@ function translation_help($path, $arg) {
}
/**
- * Implementation of hook_menu().
- */
-function translation_menu() {
- $items = array();
- $items['node/%node/translate'] = array(
- 'title' => 'Translate',
- 'page callback' => 'translation_node_overview',
- 'page arguments' => array(1),
- 'access callback' => '_translation_tab_access',
- 'access arguments' => array(1),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- );
- return $items;
-}
-
-/**
* Menu access callback.
*
* Only display translation tab for node types, which have translation enabled
@@ -82,28 +65,6 @@ function _translation_tab_access($node)
}
/**
- * Implementation of hook_perm().
- */
-function translation_perm() {
- return array(
- 'translate content' => array(
- 'title' => t('Translate content'),
- 'description' => t('Translate website content.'),
- ),
- );
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- */
-function translation_form_node_type_form_alter(&$form, &$form_state) {
- // Add translation option to content type form.
- $form['workflow']['language_content_type']['#options'][TRANSLATION_ENABLED] = t('Enabled, with translation');
- // Description based on text from locale.module.
- $form['workflow']['language_content_type']['#description'] = t('Enable multilingual support for this content type. If enabled, a language selection field will be added to the editing form, allowing you to select from one of the enabled languages. You can also turn on translation for this content type, which lets you have content translated to any of the enabled languages. If disabled, new posts are saved with the default language. Existing content will not be affected by changing this option.', array('!languages' => url('admin/settings/language')));
-}
-
-/**
* Implementation of hook_form_alter().
*
* - Add translation option to content type form.
@@ -190,123 +151,6 @@ function translation_node_view($node, $t
}
/**
- * Implementation of hook_node_prepare().
- */
-function translation_node_prepare($node) {
- // Only act if we are dealing with a content type supporting translations.
- if (translation_supported_type($node->type)) {
- if (empty($node->nid) && isset($_GET['translation']) && isset($_GET['language']) &&
- ($source_nid = $_GET['translation']) && ($language = $_GET['language']) &&
- (user_access('translate content'))) {
- // We are translating a node from a source node, so
- // load the node to be translated and populate fields.
- $source_node = node_load($source_nid);
- // Ensure we don't have an existing translation in this language.
- if (!empty($source_node->tnid)) {
- $translations = translation_node_get_translations($source_node->tnid);
- if (isset($translations[$language])) {
- $languages = language_list();
- drupal_set_message(t('A translation of %title in %language already exists, a new %type will be created instead of a translation.', array('%title' => $source_node->title, '%language' => $languages[$language]->name, '%type' => $node->type)), 'error');
- return;
- }
- }
- $node->language = $language;
- $node->translation_source = $source_node;
- $node->title = $node->translation_source->title;
- $node->body = $node->translation_source->body;
- // Let every module add custom translated fields.
- module_invoke_all('node_prepare_translation', $node);
- }
- }
-}
-
-/**
- * Implementation of hook_node_insert().
- */
-function translation_node_insert($node) {
- // Only act if we are dealing with a content type supporting translations.
- if (translation_supported_type($node->type)) {
- if (!empty($node->translation_source)) {
- if ($node->translation_source->tnid) {
- // Add node to existing translation set.
- $tnid = $node->translation_source->tnid;
- }
- else {
- // Create new translation set, using nid from the source node.
- $tnid = $node->translation_source->nid;
- db_update('node')
- ->fields(array(
- 'tnid' => $tnid,
- 'translate' => 0,
- ))
- ->condition('nid', $node->translation_source->nid)
- ->execute();
- }
- db_update('node')
- ->fields(array(
- 'tnid' => $tnid,
- 'translate' => 0,
- ))
- ->condition('nid', $node->nid)
- ->execute();
- }
- }
-}
-
-/**
- * Implementation of hook_node_update().
- */
-function translation_node_update($node) {
- // Only act if we are dealing with a content type supporting translations.
- if (translation_supported_type($node->type)) {
- if (isset($node->translation) && $node->translation && !empty($node->language) && $node->tnid) {
- // Update translation information.
- db_update('node')
- ->fields(array(
- 'tnid' => $node->tnid,
- 'translate' => $node->translation['status'],
- ))
- ->condition('nid', $node->nid)
- ->execute();
- if (!empty($node->translation['retranslate'])) {
- // This is the source node, asking to mark all translations outdated.
- db_update('node')
- ->fields(array('translate' => 1))
- ->condition('nid', $node->nid, '<>')
- ->condition('tnid', $node->tnid)
- ->execute();
- }
- }
- }
-}
-
-/**
- * Implementation of hook_node_validate().
- *
- * Ensure that duplicate translations can not be created for the same source.
- */
-function translation_node_validate($node, $form) {
- // Only act on translatable nodes with a tnid or translation_source.
- if (translation_supported_type($node->type) && (!empty($node->tnid) || !empty($form['#node']->translation_source->nid))) {
- $tnid = !empty($node->tnid) ? $node->tnid : $form['#node']->translation_source->nid;
- $translations = translation_node_get_translations($tnid);
- if (isset($translations[$node->language]) && $translations[$node->language]->nid != $node->nid ) {
- form_set_error('language', t('There is already a translation in this language.'));
- }
- }
-}
-
-/**
- * Implementation of hook_node_delete().
- */
-function translation_node_delete($node) {
- // Only act if we are dealing with a content type supporting translations.
- if (translation_supported_type($node->type)) {
- translation_remove_from_set($node);
- }
-}
-
-/**
* Remove a node from its translation set (if any)
* and update the set accordingly.
*/
Index: modules/translation/translation.node.inc
===================================================================
RCS file: modules/translation/translation.node.inc
diff -N modules/translation/translation.node.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/translation/translation.node.inc 21 May 2009 23:14:27 -0000
@@ -0,0 +1,125 @@
+type)) {
+ if (empty($node->nid) && isset($_GET['translation']) && isset($_GET['language']) &&
+ ($source_nid = $_GET['translation']) && ($language = $_GET['language']) &&
+ (user_access('translate content'))) {
+ // We are translating a node from a source node, so
+ // load the node to be translated and populate fields.
+ $source_node = node_load($source_nid);
+ // Ensure we don't have an existing translation in this language.
+ if (!empty($source_node->tnid)) {
+ $translations = translation_node_get_translations($source_node->tnid);
+ if (isset($translations[$language])) {
+ $languages = language_list();
+ drupal_set_message(t('A translation of %title in %language already exists, a new %type will be created instead of a translation.', array('%title' => $source_node->title, '%language' => $languages[$language]->name, '%type' => $node->type)), 'error');
+ return;
+ }
+ }
+ $node->language = $language;
+ $node->translation_source = $source_node;
+ $node->title = $node->translation_source->title;
+ $node->body = $node->translation_source->body;
+ // Let every module add custom translated fields.
+ module_invoke_all('node_prepare_translation', $node);
+ }
+ }
+}
+
+/**
+ * Implementation of hook_node_insert().
+ */
+function translation_node_insert($node) {
+ // Only act if we are dealing with a content type supporting translations.
+ if (translation_supported_type($node->type)) {
+ if (!empty($node->translation_source)) {
+ if ($node->translation_source->tnid) {
+ // Add node to existing translation set.
+ $tnid = $node->translation_source->tnid;
+ }
+ else {
+ // Create new translation set, using nid from the source node.
+ $tnid = $node->translation_source->nid;
+ db_update('node')
+ ->fields(array(
+ 'tnid' => $tnid,
+ 'translate' => 0,
+ ))
+ ->condition('nid', $node->translation_source->nid)
+ ->execute();
+ }
+ db_update('node')
+ ->fields(array(
+ 'tnid' => $tnid,
+ 'translate' => 0,
+ ))
+ ->condition('nid', $node->nid)
+ ->execute();
+ }
+ }
+}
+
+/**
+ * Implementation of hook_node_update().
+ */
+function translation_node_update($node) {
+ // Only act if we are dealing with a content type supporting translations.
+ if (translation_supported_type($node->type)) {
+ if (isset($node->translation) && $node->translation && !empty($node->language) && $node->tnid) {
+ // Update translation information.
+ db_update('node')
+ ->fields(array(
+ 'tnid' => $node->tnid,
+ 'translate' => $node->translation['status'],
+ ))
+ ->condition('nid', $node->nid)
+ ->execute();
+ if (!empty($node->translation['retranslate'])) {
+ // This is the source node, asking to mark all translations outdated.
+ db_update('node')
+ ->fields(array('translate' => 1))
+ ->condition('nid', $node->nid, '<>')
+ ->condition('tnid', $node->tnid)
+ ->execute();
+ }
+ }
+ }
+}
+
+/**
+ * Implementation of hook_node_validate().
+ *
+ * Ensure that duplicate translations can not be created for the same source.
+ */
+function translation_node_validate($node, $form) {
+ // Only act on translatable nodes with a tnid or translation_source.
+ if (translation_supported_type($node->type) && (!empty($node->tnid) || !empty($form['#node']->translation_source->nid))) {
+ $tnid = !empty($node->tnid) ? $node->tnid : $form['#node']->translation_source->nid;
+ $translations = translation_node_get_translations($tnid);
+ if (isset($translations[$node->language]) && $translations[$node->language]->nid != $node->nid ) {
+ form_set_error('language', t('There is already a translation in this language.'));
+ }
+ }
+}
+
+/**
+ * Implementation of hook_node_delete().
+ */
+function translation_node_delete($node) {
+ // Only act if we are dealing with a content type supporting translations.
+ if (translation_supported_type($node->type)) {
+ translation_remove_from_set($node);
+ }
+}
+
Index: modules/translation/translation.registry.inc
===================================================================
RCS file: modules/translation/translation.registry.inc
diff -N modules/translation/translation.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/translation/translation.registry.inc 21 May 2009 23:13:59 -0000
@@ -0,0 +1,25 @@
+ 'Translate',
+ 'page callback' => 'translation_node_overview',
+ 'page arguments' => array(1),
+ 'access callback' => '_translation_tab_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ );
+ return $items;
+}
+
Index: modules/translation/translation.user.inc
===================================================================
RCS file: modules/translation/translation.user.inc
diff -N modules/translation/translation.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/translation/translation.user.inc 21 May 2009 23:14:14 -0000
@@ -0,0 +1,20 @@
+ array(
+ 'title' => t('Translate content'),
+ 'description' => t('Translate website content.'),
+ ),
+ );
+}
+
Index: modules/trigger/trigger.actions.inc
===================================================================
RCS file: modules/trigger/trigger.actions.inc
diff -N modules/trigger/trigger.actions.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/trigger/trigger.actions.inc 21 May 2009 23:14:06 -0000
@@ -0,0 +1,16 @@
+ 'cron',
+ 'op' => '',
+ );
+ // Cron does not act on any specific object.
+ $object = NULL;
+ actions_do(array_keys($aids), $object, $context);
+}
+
Index: modules/trigger/trigger.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/trigger/trigger.info,v
retrieving revision 1.5
diff -u -p -r1.5 trigger.info
--- modules/trigger/trigger.info 11 Oct 2008 02:33:10 -0000 1.5
+++ modules/trigger/trigger.info 21 May 2009 23:14:40 -0000
@@ -7,3 +7,10 @@ core = 7.x
files[] = trigger.module
files[] = trigger.admin.inc
files[] = trigger.install
+files[] = trigger.registry.inc
+files[] = trigger.actions.inc
+files[] = trigger.user.inc
+files[] = trigger.node.inc
+files[] = trigger.comment.inc
+files[] = trigger.taxonomy.inc
+files[] = trigger.cron.inc
Index: modules/trigger/trigger.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/trigger/trigger.module,v
retrieving revision 1.33
diff -u -p -r1.33 trigger.module
--- modules/trigger/trigger.module 14 May 2009 08:23:15 -0000 1.33
+++ modules/trigger/trigger.module 21 May 2009 23:14:40 -0000
@@ -32,90 +32,6 @@ function trigger_help($path, $arg) {
}
/**
- * Implementation of hook_menu().
- */
-function trigger_menu() {
- $items['admin/build/trigger'] = array(
- 'title' => 'Triggers',
- 'description' => 'Tell Drupal when to execute actions.',
- 'page callback' => 'trigger_assign',
- 'access callback' => 'trigger_access_check',
- 'access arguments' => array('node'),
- );
- // We don't use a menu wildcard here because these are tabs,
- // not invisible items.
- $items['admin/build/trigger/node'] = array(
- 'title' => 'Content',
- 'page callback' => 'trigger_assign',
- 'page arguments' => array('node'),
- 'access callback' => 'trigger_access_check',
- 'access arguments' => array('node'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['admin/build/trigger/user'] = array(
- 'title' => 'Users',
- 'page callback' => 'trigger_assign',
- 'page arguments' => array('user'),
- 'access callback' => 'trigger_access_check',
- 'access arguments' => array('user'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['admin/build/trigger/comment'] = array(
- 'title' => 'Comments',
- 'page callback' => 'trigger_assign',
- 'page arguments' => array('comment'),
- 'access callback' => 'trigger_access_check',
- 'access arguments' => array('comment'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['admin/build/trigger/taxonomy'] = array(
- 'title' => 'Taxonomy',
- 'page callback' => 'trigger_assign',
- 'page arguments' => array('taxonomy'),
- 'access callback' => 'trigger_access_check',
- 'access arguments' => array('taxonomy'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['admin/build/trigger/cron'] = array(
- 'title' => 'Cron',
- 'page callback' => 'trigger_assign',
- 'page arguments' => array('cron'),
- 'access arguments' => array('administer actions'),
- 'type' => MENU_LOCAL_TASK,
- );
-
- // We want contributed modules to be able to describe
- // their hooks and have actions assignable to them.
- $hooks = module_invoke_all('hook_info');
- foreach ($hooks as $module => $hook) {
- // We've already done these.
- if (in_array($module, array('node', 'comment', 'user', 'system', 'taxonomy'))) {
- continue;
- }
- $info = db_result(db_query("SELECT info FROM {system} WHERE name = '%s'", $module));
- $info = unserialize($info);
- $nice_name = $info['name'];
- $items["admin/build/trigger/$module"] = array(
- 'title' => $nice_name,
- 'page callback' => 'trigger_assign',
- 'page arguments' => array($module),
- 'access arguments' => array($module),
- 'type' => MENU_LOCAL_TASK,
- );
- }
- $items['admin/build/trigger/unassign'] = array(
- 'title' => 'Unassign',
- 'description' => 'Unassign an action from a trigger.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('trigger_unassign'),
- 'access arguments' => array('administer actions'),
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
-}
-
-/**
* Access callback for menu system.
*/
function trigger_access_check($module) {
@@ -143,17 +59,6 @@ function _trigger_get_hook_aids($hook, $
}
/**
- * Implementation of hook_theme().
- */
-function trigger_theme() {
- return array(
- 'trigger_display' => array(
- 'arguments' => array('element'),
- ),
- );
-}
-
-/**
* Implementation of hook_forms(). We reuse code by using the
* same assignment form definition for each node-op combination.
*/
@@ -248,34 +153,6 @@ function trigger_node_view($node, $tease
}
/**
- * Implementation of hook_node_update().
- */
-function trigger_node_update($node) {
- _trigger_node($node, 'update');
-}
-
-/**
- * Implementation of hook_node_presave().
- */
-function trigger_node_presave($node) {
- _trigger_node($node, 'presave');
-}
-
-/**
- * Implementation of hook_node_insert().
- */
-function trigger_node_insert($node) {
- _trigger_node($node, 'insert');
-}
-
-/**
- * Implementation of hook_node_delete().
- */
-function trigger_node_delete($node) {
- _trigger_node($node, 'delete');
-}
-
-/**
* When an action is called in a context that does not match its type,
* the object that the action expects must be retrieved. For example, when
* an action that works on nodes is called during the comment hook, the
@@ -302,34 +179,6 @@ function _trigger_normalize_comment_cont
}
/**
- * Implementation of hook_comment_insert().
- */
-function trigger_comment_insert($form_values) {
- _trigger_comment($form_values, 'insert');
-}
-
-/**
- * Implementation of hook_comment_update().
- */
-function trigger_comment_update($form_values) {
- _trigger_comment($form_values, 'update');
-}
-
-/**
- * Implementation of hook_comment_delete().
- */
-function trigger_comment_delete($comment) {
- _trigger_comment($comment, 'delete');
-}
-
-/**
- * Implementation of hook_comment_view().
- */
-function trigger_comment_view($comment) {
- _trigger_comment($comment, 'view');
-}
-
-/**
* Helper function for implementations of hook_comment_op().
*
* @param $a1
@@ -367,20 +216,6 @@ function _trigger_comment($a1, $op) {
}
/**
- * Implementation of hook_cron().
- */
-function trigger_cron() {
- $aids = _trigger_get_hook_aids('cron');
- $context = array(
- 'hook' => 'cron',
- 'op' => '',
- );
- // Cron does not act on any specific object.
- $object = NULL;
- actions_do(array_keys($aids), $object, $context);
-}
-
-/**
* When an action is called in a context that does not match its type,
* the object that the action expects must be retrieved. For example, when
* an action that works on nodes is called during the user hook, the
@@ -412,13 +247,6 @@ function _trigger_normalize_user_context
}
/**
- * trigger_user_login
- */
-function trigger_user_login(&$edit, &$account, $category) {
- _trigger_user('login', $edit, $account, $category);
-}
-
-/**
* Implementation of hook_user_logout().
*/
function trigger_user_logout($edit, $account) {
@@ -426,32 +254,6 @@ function trigger_user_logout($edit, $acc
}
/**
- * Implementation of hook_user_insert().
- */
-function trigger_user_insert(&$edit, &$account, $category) {
- _trigger_user('insert', $edit, $account, $category);
-}
-
-/**
- * Implementation of hook_user_update().
- */
-function trigger_user_update(&$edit, &$account, $category) {
- _trigger_user('update', $edit, $account, $category);
-}
-
-/**
- * Implementation of hook_user_cancel().
- */
-function trigger_user_cancel($edit, $account, $method) {
- switch ($method) {
- case 'user_cancel_reassign':
- case 'user_cancel_delete':
- _trigger_user('delete', $edit, $account, $method);
- break;
- }
-}
-
-/**
* Implementation of hook_user_view().
*/
function trigger_user_view(&$edit, &$account, $category) {
@@ -487,24 +289,6 @@ function _trigger_user($op, &$edit, &$ac
}
/**
- * Implementation of hook_taxonomy().
- */
-function trigger_taxonomy($op, $type, $array) {
- if ($type != 'term') {
- return;
- }
- $aids = _trigger_get_hook_aids('taxonomy', $op);
- $context = array(
- 'hook' => 'taxonomy',
- 'op' => $op
- );
- $_array = (object) $array;
- foreach ($aids as $aid => $action_info) {
- actions_do($aid, $_array, $context);
- }
-}
-
-/**
* Often we generate a select field of all actions. This function
* generates the options for that select.
*
@@ -527,11 +311,3 @@ function trigger_options($type = 'all')
}
}
-/**
- * Implementation of hook_actions_delete().
- *
- * Remove all trigger entries for the given action, when deleted.
- */
-function trigger_actions_delete($aid) {
- db_query("DELETE FROM {trigger_assignments} WHERE aid = '%s'", $aid);
-}
Index: modules/trigger/trigger.node.inc
===================================================================
RCS file: modules/trigger/trigger.node.inc
diff -N modules/trigger/trigger.node.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/trigger/trigger.node.inc 21 May 2009 23:14:27 -0000
@@ -0,0 +1,36 @@
+ 'Triggers',
+ 'description' => 'Tell Drupal when to execute actions.',
+ 'page callback' => 'trigger_assign',
+ 'access callback' => 'trigger_access_check',
+ 'access arguments' => array('node'),
+ );
+ // We don't use a menu wildcard here because these are tabs,
+ // not invisible items.
+ $items['admin/build/trigger/node'] = array(
+ 'title' => 'Content',
+ 'page callback' => 'trigger_assign',
+ 'page arguments' => array('node'),
+ 'access callback' => 'trigger_access_check',
+ 'access arguments' => array('node'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/build/trigger/user'] = array(
+ 'title' => 'Users',
+ 'page callback' => 'trigger_assign',
+ 'page arguments' => array('user'),
+ 'access callback' => 'trigger_access_check',
+ 'access arguments' => array('user'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/build/trigger/comment'] = array(
+ 'title' => 'Comments',
+ 'page callback' => 'trigger_assign',
+ 'page arguments' => array('comment'),
+ 'access callback' => 'trigger_access_check',
+ 'access arguments' => array('comment'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/build/trigger/taxonomy'] = array(
+ 'title' => 'Taxonomy',
+ 'page callback' => 'trigger_assign',
+ 'page arguments' => array('taxonomy'),
+ 'access callback' => 'trigger_access_check',
+ 'access arguments' => array('taxonomy'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/build/trigger/cron'] = array(
+ 'title' => 'Cron',
+ 'page callback' => 'trigger_assign',
+ 'page arguments' => array('cron'),
+ 'access arguments' => array('administer actions'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ // We want contributed modules to be able to describe
+ // their hooks and have actions assignable to them.
+ $hooks = module_invoke_all('hook_info');
+ foreach ($hooks as $module => $hook) {
+ // We've already done these.
+ if (in_array($module, array('node', 'comment', 'user', 'system', 'taxonomy'))) {
+ continue;
+ }
+ $info = db_result(db_query("SELECT info FROM {system} WHERE name = '%s'", $module));
+ $info = unserialize($info);
+ $nice_name = $info['name'];
+ $items["admin/build/trigger/$module"] = array(
+ 'title' => $nice_name,
+ 'page callback' => 'trigger_assign',
+ 'page arguments' => array($module),
+ 'access arguments' => array($module),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ }
+ $items['admin/build/trigger/unassign'] = array(
+ 'title' => 'Unassign',
+ 'description' => 'Unassign an action from a trigger.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('trigger_unassign'),
+ 'access arguments' => array('administer actions'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function trigger_theme() {
+ return array(
+ 'trigger_display' => array(
+ 'arguments' => array('element'),
+ ),
+ );
+}
+
Index: modules/trigger/trigger.taxonomy.inc
===================================================================
RCS file: modules/trigger/trigger.taxonomy.inc
diff -N modules/trigger/trigger.taxonomy.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/trigger/trigger.taxonomy.inc 21 May 2009 23:14:34 -0000
@@ -0,0 +1,26 @@
+ 'taxonomy',
+ 'op' => $op
+ );
+ $_array = (object) $array;
+ foreach ($aids as $aid => $action_info) {
+ actions_do($aid, $_array, $context);
+ }
+}
+
Index: modules/trigger/trigger.user.inc
===================================================================
RCS file: modules/trigger/trigger.user.inc
diff -N modules/trigger/trigger.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/trigger/trigger.user.inc 21 May 2009 23:14:14 -0000
@@ -0,0 +1,41 @@
+language;
+ $message['subject'] .= t('New release(s) available for !site_name', array('!site_name' => variable_get('site_name', 'Drupal')), $langcode);
+ foreach ($params as $msg_type => $msg_reason) {
+ $message['body'][] = _update_message_text($msg_type, $msg_reason, FALSE, $language);
+ }
+ $message['body'][] = t('See the available updates page for more information:', array(), $langcode) . "\n" . url('admin/reports/updates', array('absolute' => TRUE, 'language' => $language));
+}
+
Index: modules/update/update.cron.inc
===================================================================
RCS file: modules/update/update.cron.inc
diff -N modules/update/update.cron.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/update/update.cron.inc 21 May 2009 23:14:40 -0000
@@ -0,0 +1,22 @@
+ $interval)) {
+ update_refresh();
+ _update_cron_notify();
+ }
+}
+
Index: modules/update/update.form.inc
===================================================================
RCS file: modules/update/update.form.inc
diff -N modules/update/update.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/update/update.form.inc 21 May 2009 23:14:46 -0000
@@ -0,0 +1,32 @@
+ 'Available updates',
- 'description' => 'Get a status report about available updates for your installed modules and themes.',
- 'page callback' => 'update_status',
- 'access arguments' => array('administer site configuration'),
- 'weight' => 10,
- );
- $items['admin/settings/updates'] = array(
- 'title' => 'Updates',
- 'description' => 'Change frequency of checks for available updates to your installed modules and themes, and how you would like to be notified.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('update_settings'),
- 'access arguments' => array('administer site configuration'),
- );
- $items['admin/reports/updates/check'] = array(
- 'title' => 'Manual update check',
- 'page callback' => 'update_manual_status',
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
-}
-
-/**
- * Implementation of the hook_theme() registry.
- */
-function update_theme() {
- return array(
- 'update_settings' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'update_report' => array(
- 'arguments' => array('data' => NULL),
- ),
- 'update_version' => array(
- 'arguments' => array('version' => NULL, 'tag' => NULL, 'class' => NULL),
- ),
- );
-}
-
-/**
* Implementation of hook_requirements().
*
* @return
@@ -272,44 +225,6 @@ function _update_requirement_check($proj
}
/**
- * Implementation of hook_cron().
- */
-function update_cron() {
- $frequency = variable_get('update_check_frequency', 1);
- $interval = 60 * 60 * 24 * $frequency;
- // Cron should check for updates if there is no update data cached or if the
- // configured update interval has elapsed.
- if (!_update_cache_get('update_available_releases') || ((REQUEST_TIME - variable_get('update_last_check', 0)) > $interval)) {
- update_refresh();
- _update_cron_notify();
- }
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- *
- * Adds a submit handler to the system modules and themes forms, so that if a
- * site admin saves either form, we invalidate the cache of available updates.
- *
- * @see _update_cache_clear()
- */
-function update_form_system_themes_form_alter(&$form, $form_state) {
- $form['#submit'][] = 'update_cache_clear_submit';
-}
-
-/**
- * Implementation of hook_form_FORM_ID_alter().
- *
- * Adds a submit handler to the system modules and themes forms, so that if a
- * site admin saves either form, we invalidate the cache of available updates.
- *
- * @see _update_cache_clear()
- */
-function update_form_system_modules_alter(&$form, $form_state) {
- $form['#submit'][] = 'update_cache_clear_submit';
-}
-
-/**
* Helper function for use as a form submit callback.
*/
function update_cache_clear_submit($form, &$form_state) {
@@ -383,35 +298,6 @@ function update_refresh() {
}
/**
- * Implementation of hook_mail().
- *
- * Constructs the email notification message when the site is out of date.
- *
- * @param $key
- * Unique key to indicate what message to build, always 'status_notify'.
- * @param $message
- * Reference to the message array being built.
- * @param $params
- * Array of parameters to indicate what kind of text to include in the
- * message body. This is a keyed array of message type ('core' or 'contrib')
- * as the keys, and the status reason constant (UPDATE_NOT_SECURE, etc) for
- * the values.
- *
- * @see drupal_mail()
- * @see _update_cron_notify()
- * @see _update_message_text()
- */
-function update_mail($key, &$message, $params) {
- $language = $message['language'];
- $langcode = $language->language;
- $message['subject'] .= t('New release(s) available for !site_name', array('!site_name' => variable_get('site_name', 'Drupal')), $langcode);
- foreach ($params as $msg_type => $msg_reason) {
- $message['body'][] = _update_message_text($msg_type, $msg_reason, FALSE, $language);
- }
- $message['body'][] = t('See the available updates page for more information:', array(), $langcode) . "\n" . url('admin/reports/updates', array('absolute' => TRUE, 'language' => $language));
-}
-
-/**
* Helper function to return the appropriate message text when the site is out
* of date or missing a security update.
*
@@ -596,28 +482,5 @@ function _update_cache_clear($cid = NULL
}
/**
- * Implementation of hook_flush_caches().
- *
- * Called from update.php (among others) to flush the caches.
- * Since we're running update.php, we are likely to install a new version of
- * something, in which case, we want to check for available update data again.
- * However, because we have our own caching system, we need to directly clear
- * the database table ourselves at this point and return nothing, for example,
- * on sites that use memcache where cache_clear_all() won't know how to purge
- * this data.
- *
- * However, we only want to do this from update.php, since otherwise, we'd
- * lose all the available update data on every cron run. So, we specifically
- * check if the site is in MAINTENANCE_MODE == 'update' (which indicates
- * update.php is running, not update module... alas for overloaded names).
- */
-function update_flush_caches() {
- if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
- _update_cache_clear();
- }
- return array();
-}
-
-/**
* @} End of "defgroup update_status_cache".
*/
Index: modules/update/update.registry.inc
===================================================================
RCS file: modules/update/update.registry.inc
diff -N modules/update/update.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/update/update.registry.inc 21 May 2009 23:13:59 -0000
@@ -0,0 +1,78 @@
+ 'Available updates',
+ 'description' => 'Get a status report about available updates for your installed modules and themes.',
+ 'page callback' => 'update_status',
+ 'access arguments' => array('administer site configuration'),
+ 'weight' => 10,
+ );
+ $items['admin/settings/updates'] = array(
+ 'title' => 'Updates',
+ 'description' => 'Change frequency of checks for available updates to your installed modules and themes, and how you would like to be notified.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('update_settings'),
+ 'access arguments' => array('administer site configuration'),
+ );
+ $items['admin/reports/updates/check'] = array(
+ 'title' => 'Manual update check',
+ 'page callback' => 'update_manual_status',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Implementation of the hook_theme() registry.
+ */
+function update_theme() {
+ return array(
+ 'update_settings' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'update_report' => array(
+ 'arguments' => array('data' => NULL),
+ ),
+ 'update_version' => array(
+ 'arguments' => array('version' => NULL, 'tag' => NULL, 'class' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_flush_caches().
+ *
+ * Called from update.php (among others) to flush the caches.
+ * Since we're running update.php, we are likely to install a new version of
+ * something, in which case, we want to check for available update data again.
+ * However, because we have our own caching system, we need to directly clear
+ * the database table ourselves at this point and return nothing, for example,
+ * on sites that use memcache where cache_clear_all() won't know how to purge
+ * this data.
+ *
+ * However, we only want to do this from update.php, since otherwise, we'd
+ * lose all the available update data on every cron run. So, we specifically
+ * check if the site is in MAINTENANCE_MODE == 'update' (which indicates
+ * update.php is running, not update module... alas for overloaded names).
+ */
+function update_flush_caches() {
+ if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
+ _update_cache_clear();
+ }
+ return array();
+}
+
Index: modules/upload/upload.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.info,v
retrieving revision 1.8
diff -u -p -r1.8 upload.info
--- modules/upload/upload.info 11 Oct 2008 02:33:13 -0000 1.8
+++ modules/upload/upload.info 21 May 2009 23:14:27 -0000
@@ -7,3 +7,6 @@ core = 7.x
files[] = upload.module
files[] = upload.admin.inc
files[] = upload.install
+files[] = upload.registry.inc
+files[] = upload.user.inc
+files[] = upload.node.inc
Index: modules/upload/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v
retrieving revision 1.239
diff -u -p -r1.239 upload.module
--- modules/upload/upload.module 21 May 2009 12:00:06 -0000 1.239
+++ modules/upload/upload.module 21 May 2009 23:14:27 -0000
@@ -23,39 +23,6 @@ function upload_help($path, $arg) {
}
/**
- * Implementation of hook_theme().
- */
-function upload_theme() {
- return array(
- 'upload_attachments' => array(
- 'arguments' => array('elements' => NULL),
- ),
- 'upload_form_current' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'upload_form_new' => array(
- 'arguments' => array('form' => NULL),
- ),
- );
-}
-
-/**
- * Implementation of hook_perm().
- */
-function upload_perm() {
- return array(
- 'upload files' => array(
- 'title' => t('Upload files'),
- 'description' => t('Attach images and other files to content.'),
- ),
- 'view uploaded files' => array(
- 'title' => t('View uploaded files'),
- 'description' => t('View and download files attached to content.'),
- ),
- );
-}
-
-/**
* Inject links into $node for attachments.
*/
function upload_node_links($node, $teaser) {
@@ -83,26 +50,6 @@ function upload_node_links($node, $tease
}
/**
- * Implementation of hook_menu().
- */
-function upload_menu() {
- $items['upload/js'] = array(
- 'page callback' => 'upload_js',
- 'access arguments' => array('upload files'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/settings/uploads'] = array(
- 'title' => 'File uploads',
- 'description' => 'Control how files may be attached to content.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('upload_admin_settings'),
- 'access arguments' => array('administer site configuration'),
- 'type' => MENU_NORMAL_ITEM,
- );
- return $items;
-}
-
-/**
* Determine the limitations on files that a given user may upload. The user
* may be in multiple roles so we select the most permissive limitations from
* all of their roles.
@@ -382,50 +329,6 @@ function upload_node_view($node, $teaser
}
/**
- * Implementation of hook_node_insert().
- */
-function upload_node_insert($node) {
- if (user_access('upload files')) {
- upload_save($node);
- }
-}
-
-/**
- * Implementation of hook_node_update().
- */
-function upload_node_update($node) {
- if (user_access('upload files')) {
- upload_save($node);
- }
-}
-
-/**
- * Implementation of hook_node_delete().
- */
-function upload_node_delete($node) {
- db_delete('upload')->condition('nid', $node->nid)->execute();
- if (!is_array($node->files)) {
- return;
- }
- foreach ($node->files as $file) {
- file_delete($file);
- }
-}
-
-/**
- * Implementation of hook_node_delete_revision().
- */
-function upload_node_delete_revision($node) {
- db_delete('upload')->condition('vid', $node->vid)->execute();
- if (!is_array($node->files)) {
- return;
- }
- foreach ($node->files as $file) {
- file_delete($file);
- }
-}
-
-/**
* Implementation of hook_node_search_result().
*/
function upload_node_search_result($node) {
Index: modules/upload/upload.node.inc
===================================================================
RCS file: modules/upload/upload.node.inc
diff -N modules/upload/upload.node.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.node.inc 21 May 2009 23:14:27 -0000
@@ -0,0 +1,52 @@
+condition('nid', $node->nid)->execute();
+ if (!is_array($node->files)) {
+ return;
+ }
+ foreach ($node->files as $file) {
+ file_delete($file);
+ }
+}
+
+/**
+ * Implementation of hook_node_delete_revision().
+ */
+function upload_node_delete_revision($node) {
+ db_delete('upload')->condition('vid', $node->vid)->execute();
+ if (!is_array($node->files)) {
+ return;
+ }
+ foreach ($node->files as $file) {
+ file_delete($file);
+ }
+}
+
Index: modules/upload/upload.registry.inc
===================================================================
RCS file: modules/upload/upload.registry.inc
diff -N modules/upload/upload.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.registry.inc 21 May 2009 23:13:59 -0000
@@ -0,0 +1,45 @@
+ 'upload_js',
+ 'access arguments' => array('upload files'),
+ 'type' => MENU_CALLBACK,
+ );
+ $items['admin/settings/uploads'] = array(
+ 'title' => 'File uploads',
+ 'description' => 'Control how files may be attached to content.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('upload_admin_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_NORMAL_ITEM,
+ );
+ return $items;
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function upload_theme() {
+ return array(
+ 'upload_attachments' => array(
+ 'arguments' => array('elements' => NULL),
+ ),
+ 'upload_form_current' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ 'upload_form_new' => array(
+ 'arguments' => array('form' => NULL),
+ ),
+ );
+}
+
Index: modules/upload/upload.user.inc
===================================================================
RCS file: modules/upload/upload.user.inc
diff -N modules/upload/upload.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.user.inc 21 May 2009 23:14:14 -0000
@@ -0,0 +1,24 @@
+ array(
+ 'title' => t('Upload files'),
+ 'description' => t('Attach images and other files to content.'),
+ ),
+ 'view uploaded files' => array(
+ 'title' => t('View uploaded files'),
+ 'description' => t('View and download files attached to content.'),
+ ),
+ );
+}
+
Index: modules/user/user.actions.inc
===================================================================
RCS file: modules/user/user.actions.inc
diff -N modules/user/user.actions.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.actions.inc 21 May 2009 23:14:06 -0000
@@ -0,0 +1,55 @@
+ array(
+ 'description' => t('Block current user'),
+ 'type' => 'user',
+ 'configurable' => FALSE,
+ 'hooks' => array(),
+ ),
+ );
+}
+
+/**
+ * Implementation of a Drupal action.
+ * Blocks the current user.
+ */
+function user_block_user_action(&$object, $context = array()) {
+ if (isset($object->uid)) {
+ $uid = $object->uid;
+ }
+ elseif (isset($context['uid'])) {
+ $uid = $context['uid'];
+ }
+ else {
+ global $user;
+ $uid = $user->uid;
+ }
+ db_update('users')
+ ->fields(array('status' => 0))
+ ->condition('uid', $uid)
+ ->execute();
+ drupal_session_destroy_uid($uid);
+ watchdog('action', 'Blocked user %name.', array('%name' => $user->name));
+}
+
Index: modules/user/user.block.inc
===================================================================
RCS file: modules/user/user.block.inc
diff -N modules/user/user.block.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.block.inc 21 May 2009 23:14:19 -0000
@@ -0,0 +1,69 @@
+ 'select',
+ '#title' => t('Number of users to display'),
+ '#default_value' => variable_get('user_block_whois_new_count', 5),
+ '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)),
+ );
+ return $form;
+
+ case 'online':
+ $period = drupal_map_assoc(array(30, 60, 120, 180, 300, 600, 900, 1800, 2700, 3600, 5400, 7200, 10800, 21600, 43200, 86400), 'format_interval');
+ $form['user_block_seconds_online'] = array('#type' => 'select', '#title' => t('User activity'), '#default_value' => variable_get('user_block_seconds_online', 900), '#options' => $period, '#description' => t('A user is considered online for this long after they have last viewed a page.'));
+ $form['user_block_max_list_count'] = array('#type' => 'select', '#title' => t('User list length'), '#default_value' => variable_get('user_block_max_list_count', 10), '#options' => drupal_map_assoc(array(0, 5, 10, 15, 20, 25, 30, 40, 50, 75, 100)), '#description' => t('Maximum number of currently online users to display.'));
+ $form['user_block_cache'] = array('#markup' => '
If page caching is disabled, the block shows the number of anonymous and authenticated users, respectively. If page caching is enabled, only the number of authenticated users is displayed.
');
+ return $form;
+ }
+}
+
+/**
+ * Implementation of hook_block_save().
+ */
+function user_block_save($delta = '', $edit = array()) {
+ global $user;
+
+ switch ($delta) {
+ case 'new':
+ variable_set('user_block_whois_new_count', $edit['user_block_whois_new_count']);
+ break;
+
+ case 'online':
+ variable_set('user_block_seconds_online', $edit['user_block_seconds_online']);
+ variable_set('user_block_max_list_count', $edit['user_block_max_list_count']);
+ break;
+ }
+}
+
Index: modules/user/user.comment.inc
===================================================================
RCS file: modules/user/user.comment.inc
diff -N modules/user/user.comment.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.comment.inc 21 May 2009 23:14:31 -0000
@@ -0,0 +1,20 @@
+signature)) {
+ $comment->signature = check_markup($comment->signature, $comment->format);
+ }
+ else {
+ $comment->signature = '';
+ }
+}
+
Index: modules/user/user.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.info,v
retrieving revision 1.10
diff -u -p -r1.10 user.info
--- modules/user/user.info 12 Oct 2008 01:23:07 -0000 1.10
+++ modules/user/user.info 21 May 2009 23:14:36 -0000
@@ -9,3 +9,9 @@ files[] = user.admin.inc
files[] = user.pages.inc
files[] = user.install
required = TRUE
+files[] = user.registry.inc
+files[] = user.actions.inc
+files[] = user.user.inc
+files[] = user.block.inc
+files[] = user.comment.inc
+files[] = user.search.inc
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.987
diff -u -p -r1.987 user.module
--- modules/user/user.module 16 May 2009 15:23:16 -0000 1.987
+++ modules/user/user.module 21 May 2009 23:14:36 -0000
@@ -31,51 +31,6 @@ function user_module_invoke($type, &$arr
}
/**
- * Implementation of hook_theme().
- */
-function user_theme() {
- return array(
- 'user_picture' => array(
- 'arguments' => array('account' => NULL),
- 'template' => 'user-picture',
- ),
- 'user_profile' => array(
- 'arguments' => array('elements' => NULL),
- 'template' => 'user-profile',
- ),
- 'user_profile_category' => array(
- 'arguments' => array('element' => NULL),
- 'template' => 'user-profile-category',
- ),
- 'user_profile_item' => array(
- 'arguments' => array('element' => NULL),
- 'template' => 'user-profile-item',
- ),
- 'user_list' => array(
- 'arguments' => array('users' => NULL, 'title' => NULL),
- ),
- 'user_admin_perm' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'user_admin_new_role' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'user_admin_account' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'user_filter_form' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'user_filters' => array(
- 'arguments' => array('form' => NULL),
- ),
- 'user_signature' => array(
- 'arguments' => array('signature' => NULL),
- ),
- );
-}
-
-/**
* Implementation of hook_fieldable_info().
*/
function user_fieldable_info() {
@@ -774,38 +729,6 @@ function user_is_blocked($name) {
}
/**
- * Implementation of hook_perm().
- */
-function user_perm() {
- return array(
- 'administer permissions' => array(
- 'title' => t('Administer permissions'),
- 'description' => t('Manage the permissions assigned to user roles. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
- ),
- 'administer users' => array(
- 'title' => t('Administer users'),
- 'description' => t('Manage or block users, and manage their role assignments.'),
- ),
- 'access user profiles' => array(
- 'title' => t('Access user profiles'),
- 'description' => t('View profiles of users on the site, which may contain personal information.'),
- ),
- 'change own username' => array(
- 'title' => t('Change own username'),
- 'description' => t('Select a different username.'),
- ),
- 'cancel account' => array(
- 'title' => t('Cancel account'),
- 'description' => t('Remove or disable own user account and unpublish, anonymize, or remove own submissions depending on the configured user settings.', array('@user-settings-url' => url('admin/user/settings'))),
- ),
- 'select account cancellation method' => array(
- 'title' => t('Select method for cancelling own account'),
- 'description' => t('Select the method for cancelling own user account. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
- ),
- );
-}
-
-/**
* Implementation of hook_file_download().
*
* Ensure that user pictures (avatars) are always downloadable.
@@ -841,42 +764,6 @@ function user_file_delete($file) {
}
/**
- * Implementation of hook_search().
- */
-function user_search($op = 'search', $keys = NULL, $skip_access_check = FALSE) {
- switch ($op) {
- case 'name':
- if ($skip_access_check || user_access('access user profiles')) {
- return t('Users');
- }
- case 'search':
- if (user_access('access user profiles')) {
- $find = array();
- // Replace wildcards with MySQL/PostgreSQL wildcards.
- $keys = preg_replace('!\*+!', '%', $keys);
- $query = db_select('users')->extend('PagerDefault');
- $query->fields('users', array('name', 'uid', 'mail'));
- if (user_access('administer users')) {
- // Administrators can also search in the otherwise private email field.
- $query->condition(db_or()->
- where('LOWER(name) LIKE LOWER(:name)', array(':name' => "%$keys%"))->
- where('LOWER(mail) LIKE LOWER(:mail)', array(':mail' => "%$keys%")));
- }
- else {
- $query->where('LOWER(name) LIKE LOWER(:name)', array(':name' => "%$keys%"));
- }
- $result = $query
- ->limit(15)
- ->execute();
- foreach ($result as $account) {
- $find[] = array('title' => $account->name . ' (' . $account->mail . ')', 'link' => url('user/' . $account->uid, array('absolute' => TRUE)));
- }
- return $find;
- }
- }
-}
-
-/**
* Implementation of hook_elements().
*/
function user_elements() {
@@ -914,86 +801,6 @@ function user_user_view(&$edit, &$accoun
);
}
-/**
- * Implementation of hook_user_form.
- */
-function user_user_form(&$edit, &$account, $category = NULL) {
- if ($category == 'account') {
- $form_state = array();
- return user_edit_form($form_state, (isset($account->uid) ? $account->uid : FALSE), $edit);
- }
-}
-
-/**
- * Implementation of hook_user_validate().
- */
-function user_user_validate(&$edit, &$account, $category = NULL) {
- if ($category == 'account') {
- $uid = isset($account->uid) ? $account->uid : FALSE;
- // Validate the username when: new user account; or user is editing own account and can change username; or an admin user.
- if (!$uid || ($GLOBALS['user']->uid == $uid && user_access('change own username')) || user_access('administer users')) {
- if ($error = user_validate_name($edit['name'])) {
- form_set_error('name', $error);
- }
- elseif ((bool) db_query_range("SELECT 1 FROM {users} WHERE uid != :uid AND LOWER(name) = LOWER(:name)", array(':uid' => $uid, ':name' => $edit['name']), 0, 1)->fetchField()) {
- form_set_error('name', t('The name %name is already taken.', array('%name' => $edit['name'])));
- }
- }
-
- // Validate the e-mail address, and check if it is taken by an existing user.
- if ($error = user_validate_mail($edit['mail'])) {
- form_set_error('mail', $error);
- }
- elseif ((bool) db_query_range("SELECT 1 FROM {users} WHERE uid != :uid AND LOWER(mail) = LOWER(:mail)", array(':uid' => $uid, ':mail' => $edit['mail']), 0, 1)->fetchField()) {
- // Format error message dependent on whether the user is logged in or not.
- if ($GLOBALS['user']->uid) {
- form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => $edit['mail'])));
- }
- else {
- form_set_error('mail', t('The e-mail address %email is already registered. Have you forgotten your password?', array('%email' => $edit['mail'], '@password' => url('user/password'))));
- }
- }
-
- // Make sure the signature isn't longer than the size of the database field.
- // Signatures are disabled by default, so make sure it exists first.
- if (isset($edit['signature'])) {
- $user_schema = drupal_get_schema('users');
- if (strlen($edit['signature']) > $user_schema['fields']['signature']['length']) {
- form_set_error('signature', t('The signature is too long: it must be %max characters or less.', array('%max' => $user_schema['fields']['signature']['length'])));
- }
- }
- }
-}
-
-/**
- * Implementation of hook_user_submit().
- */
-function user_user_submit(&$edit, &$account, $category = NULL) {
- if ($category == 'account') {
- if (!empty($edit['picture_upload'])) {
- $edit['picture'] = $edit['picture_upload'];
- }
- // Delete picture if requested, and if no replacement picture was given.
- elseif (!empty($edit['picture_delete'])) {
- $edit['picture'] = NULL;
- }
- // Remove these values so they don't end up serialized in the data field.
- $edit['picture_upload'] = NULL;
- $edit['picture_delete'] = NULL;
-
- if (isset($edit['roles'])) {
- $edit['roles'] = array_filter($edit['roles']);
- }
- }
-}
-
-/**
- * Implementation of hook_user_categories.
- */
-function user_user_categories($edit, $account, $category = NULL) {
- return array(array('name' => 'account', 'title' => t('Account settings'), 'weight' => 1));
-}
-
function user_login_block() {
$form = array(
'#action' => url($_GET['q'], array('query' => drupal_get_destination())),
@@ -1026,67 +833,6 @@ function user_login_block() {
}
/**
- * Implementation of hook_block_list().
- */
-function user_block_list() {
- global $user;
-
- $blocks['login']['info'] = t('User login');
- // Not worth caching.
- $blocks['login']['cache'] = BLOCK_NO_CACHE;
-
- $blocks['new']['info'] = t('Who\'s new');
-
- // Too dynamic to cache.
- $blocks['online']['info'] = t('Who\'s online');
- $blocks['online']['cache'] = BLOCK_NO_CACHE;
- return $blocks;
-}
-
-/**
- * Implementation of hook_block_configure().
- */
-function user_block_configure($delta = '') {
- global $user;
-
- switch($delta) {
- case 'new':
- $form['user_block_whois_new_count'] = array(
- '#type' => 'select',
- '#title' => t('Number of users to display'),
- '#default_value' => variable_get('user_block_whois_new_count', 5),
- '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)),
- );
- return $form;
-
- case 'online':
- $period = drupal_map_assoc(array(30, 60, 120, 180, 300, 600, 900, 1800, 2700, 3600, 5400, 7200, 10800, 21600, 43200, 86400), 'format_interval');
- $form['user_block_seconds_online'] = array('#type' => 'select', '#title' => t('User activity'), '#default_value' => variable_get('user_block_seconds_online', 900), '#options' => $period, '#description' => t('A user is considered online for this long after they have last viewed a page.'));
- $form['user_block_max_list_count'] = array('#type' => 'select', '#title' => t('User list length'), '#default_value' => variable_get('user_block_max_list_count', 10), '#options' => drupal_map_assoc(array(0, 5, 10, 15, 20, 25, 30, 40, 50, 75, 100)), '#description' => t('Maximum number of currently online users to display.'));
- $form['user_block_cache'] = array('#markup' => '
If page caching is disabled, the block shows the number of anonymous and authenticated users, respectively. If page caching is enabled, only the number of authenticated users is displayed.