' . 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.') . '
';
+ }
+
+}
+
+/**
+ * Implement hook_form_FORM_ID_alter().
+ */
+function block_form_system_themes_form_alter(&$form, &$form_state) {
+ // This function needs to fire before the theme changes are recorded in the
+ // database, otherwise it will populate the default list of blocks from the
+ // new theme, which is empty.
+ array_unshift($form['#submit'], 'block_system_themes_form_submit');
+}
+
+/**
+ * Initialize blocks for enabled themes.
+ */
+function block_system_themes_form_submit(&$form, &$form_state) {
+ if ($form_state['values']['op'] == t('Save configuration')) {
+ if (is_array($form_state['values']['status'])) {
+ foreach ($form_state['values']['status'] as $key => $choice) {
+ if ($choice || $form_state['values']['theme_default'] == $key) {
+ block_initialize_theme_blocks($key);
+ }
+ }
+ }
+ if ($form_state['values']['admin_theme'] && $form_state['values']['admin_theme'] != variable_get('admin_theme', 0)) {
+ // If we're changing themes, make sure the theme has its blocks initialized.
+ $has_blocks = (bool) db_query_range('SELECT 1 FROM {block} WHERE theme = :theme', array(':theme' => $form_state['values']['admin_theme']), 0, 1)->fetchField();
+ if (!$has_blocks) {
+ block_initialize_theme_blocks($form_state['values']['admin_theme']);
+ }
+ }
+ }
+}
+
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 5 Jun 2009 21:45:42 -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.341
diff -u -p -r1.341 block.module
--- modules/block/block.module 31 May 2009 07:46:54 -0000 1.341
+++ modules/block/block.module 5 Jun 2009 21:45:44 -0000
@@ -88,91 +88,6 @@ function block_help($path, $arg) {
}
/**
- * Implement 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',
- 'file' => 'block.admin.inc',
- 'arguments' => array('form' => NULL),
- ),
- );
-}
-
-/**
- * Implement 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.'),
- ),
- );
-}
-
-/**
- * Implement 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) {
@@ -181,39 +96,6 @@ function _block_themes_access($theme) {
}
/**
- * Implement hook_block_list().
- */
-function block_block_list() {
- $blocks = array();
-
- $result = db_query('SELECT bid, info FROM {box} ORDER BY info');
- foreach ($result as $block) {
- $blocks[$block->bid]['info'] = $block->info;
- // Not worth caching.
- $blocks[$block->bid]['cache'] = BLOCK_NO_CACHE;
- }
- return $blocks;
-}
-
-/**
- * Implement hook_block_configure().
- */
-function block_block_configure($delta = 0, $edit = array()) {
- $box = array('format' => FILTER_FORMAT_DEFAULT);
- if ($delta) {
- $box = block_box_get($delta);
- }
- return block_box_form($box);
-}
-
-/**
- * Implement hook_block_save().
- */
-function block_block_save($delta = 0, $edit = array()) {
- block_box_save($edit, $delta);
-}
-
-/**
* Implement hook_block_view().
*
* Generates the administrator-defined blocks for display.
@@ -361,156 +243,6 @@ function _block_rehash() {
return $blocks;
}
-function block_box_get($bid) {
- return db_query("SELECT * FROM {box} WHERE bid = :bid", array(':bid' => $bid))->fetchAssoc();
-}
-
-/**
- * Define the custom block form.
- */
-function block_box_form($edit = array()) {
- $edit += array(
- 'info' => '',
- 'body' => '',
- );
- $form['info'] = array(
- '#type' => 'textfield',
- '#title' => t('Block description'),
- '#default_value' => $edit['info'],
- '#maxlength' => 64,
- '#description' => t('A brief description of your block. Used on the block overview page.', array('@overview' => url('admin/build/block'))),
- '#required' => TRUE,
- '#weight' => -19,
- );
- $form['body_field']['#weight'] = -17;
- $form['body_field']['body'] = array(
- '#type' => 'textarea',
- '#title' => t('Block body'),
- '#default_value' => $edit['body'],
- '#text_format' => isset($edit['format']) ? $edit['format'] : FILTER_FORMAT_DEFAULT,
- '#rows' => 15,
- '#description' => t('The content of the block as shown to the user.'),
- '#required' => TRUE,
- '#weight' => -17,
- '#access' => filter_access($edit['format']),
- );
-
- return $form;
-}
-
-function block_box_save($edit, $delta) {
- db_update('box')
- ->fields(array(
- 'body' => $edit['body'],
- 'info' => $edit['info'],
- 'format' => $edit['body_format'],
- ))
- ->condition('bid', $delta)
- ->execute();
- return TRUE;
-}
-
-/**
- * Implement 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);
- foreach ($result as $block) {
- $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;
- }
- }
-}
-
-/**
- * Implement hook_user_validate().
- */
-function block_user_validate(&$edit, &$account, $category = NULL) {
- if (empty($edit['block'])) {
- $edit['block'] = array();
- }
- return $edit;
-}
-
-/**
- * Implement 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_query_range("SELECT 1 FROM {block} b WHERE module = 'user' AND delta = 'online' AND status = 1", array(), 0, 1)->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.') . '
' . t('Your PHP settings limit the maximum file size per upload to %size.', array('%size' => format_size(file_upload_max_size()))) . '
');
+
+ $roles = user_roles(FALSE, 'administer content with blog api');
+ $form['roles'] = array('#type' => 'value', '#value' => $roles);
+
+ foreach ($roles as $rid => $role) {
+ $form['settings_role_' . $rid] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Settings for @role', array('@role' => $role)),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ );
+ $form['settings_role_' . $rid]['blogapi_extensions_' . $rid] = array(
+ '#type' => 'textfield',
+ '#title' => t('Permitted file extensions'),
+ '#default_value' => variable_get('blogapi_extensions_' . $rid, $blogapi_extensions_default),
+ '#maxlength' => 255,
+ '#description' => t('Extensions that users in this role can upload. Separate extensions with a space and do not include the leading dot.'),
+ );
+ $form['settings_role_' . $rid]['blogapi_uploadsize_' . $rid] = array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum file size per upload'),
+ '#default_value' => variable_get('blogapi_uploadsize_' . $rid, $blogapi_uploadsize_default),
+ '#size' => 5,
+ '#maxlength' => 5,
+ '#description' => t('The maximum size of a file a user can upload (in megabytes).'),
+ );
+ $form['settings_role_' . $rid]['blogapi_usersize_' . $rid] = array(
+ '#type' => 'textfield',
+ '#title' => t('Total file size per user'),
+ '#default_value' => variable_get('blogapi_usersize_' . $rid, $blogapi_usersize_default),
+ '#size' => 5,
+ '#maxlength' => 5,
+ '#description' => t('The maximum size of all files a user can have on the site (in megabytes).'),
+ );
+ }
+
+ return system_settings_form($form, FALSE);
+}
+
Index: modules/blogapi/blogapi.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.info,v
retrieving revision 1.9
diff -u -p -r1.9 blogapi.info
--- modules/blogapi/blogapi.info 11 Oct 2008 02:32:37 -0000 1.9
+++ modules/blogapi/blogapi.info 5 Jun 2009 21:45:45 -0000
@@ -7,3 +7,7 @@ version = VERSION
core = 7.x
files[] = blogapi.module
files[] = blogapi.install
+files[] = blogapi.registry.inc
+files[] = blogapi.user.inc
+files[] = blogapi.xmlrpc.inc
+files[] = blogapi.admin.inc
Index: modules/blogapi/blogapi.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.module,v
retrieving revision 1.154
diff -u -p -r1.154 blogapi.module
--- modules/blogapi/blogapi.module 4 Jun 2009 03:33:27 -0000 1.154
+++ modules/blogapi/blogapi.module 5 Jun 2009 21:45:45 -0000
@@ -21,307 +21,6 @@ function blogapi_help($path, $arg) {
}
/**
- * Implement hook_perm().
- */
-function blogapi_perm() {
- return array(
- 'administer content with blog api' => array(
- 'title' => t('Administer content with blog API'),
- 'description' => t('Manage website content from external tools.'),
- ),
- );
-}
-
-/**
- * Implement 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,136 +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() {
- $node_types = array_map('check_plain', node_type_get_names());
- $defaults = isset($node_types['blog']) ? array('blog' => 1) : array();
- $form['blogapi_node_types'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Enable for external blogging clients'),
- '#required' => TRUE,
- '#default_value' => variable_get('blogapi_node_types', $defaults),
- '#options' => $node_types,
- '#description' => t('Select the content types available to external blogging clients via Blog API. If supported, each enabled content type will be displayed as a separate "blog" by the external client.')
- );
-
- $blogapi_extensions_default = variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp');
- $blogapi_uploadsize_default = variable_get('blogapi_uploadsize_default', 1);
- $blogapi_usersize_default = variable_get('blogapi_usersize_default', 1);
-
- $form['settings_general'] = array(
- '#type' => 'fieldset',
- '#title' => t('File settings'),
- '#collapsible' => TRUE,
- );
-
- $form['settings_general']['blogapi_extensions_default'] = array(
- '#type' => 'textfield',
- '#title' => t('Default permitted file extensions'),
- '#default_value' => $blogapi_extensions_default,
- '#maxlength' => 255,
- '#description' => t('Default extensions that users can upload. Separate extensions with a space and do not include the leading dot.'),
- );
-
- $form['settings_general']['blogapi_uploadsize_default'] = array(
- '#type' => 'textfield',
- '#title' => t('Default maximum file size per upload'),
- '#default_value' => $blogapi_uploadsize_default,
- '#size' => 5,
- '#maxlength' => 5,
- '#description' => t('The default maximum file size a user can upload.'),
- '#field_suffix' => t('MB')
- );
-
- $form['settings_general']['blogapi_usersize_default'] = array(
- '#type' => 'textfield',
- '#title' => t('Default total file size per user'),
- '#default_value' => $blogapi_usersize_default,
- '#size' => 5,
- '#maxlength' => 5,
- '#description' => t('The default maximum size of all files a user can have on the site.'),
- '#field_suffix' => t('MB')
- );
-
- $form['settings_general']['upload_max_size'] = array('#value' => '
' . t('Your PHP settings limit the maximum file size per upload to %size.', array('%size' => format_size(file_upload_max_size()))) . '
');
-
- $roles = user_roles(FALSE, 'administer content with blog api');
- $form['roles'] = array('#type' => 'value', '#value' => $roles);
-
- foreach ($roles as $rid => $role) {
- $form['settings_role_' . $rid] = array(
- '#type' => 'fieldset',
- '#title' => t('Settings for @role', array('@role' => $role)),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- );
- $form['settings_role_' . $rid]['blogapi_extensions_' . $rid] = array(
- '#type' => 'textfield',
- '#title' => t('Permitted file extensions'),
- '#default_value' => variable_get('blogapi_extensions_' . $rid, $blogapi_extensions_default),
- '#maxlength' => 255,
- '#description' => t('Extensions that users in this role can upload. Separate extensions with a space and do not include the leading dot.'),
- );
- $form['settings_role_' . $rid]['blogapi_uploadsize_' . $rid] = array(
- '#type' => 'textfield',
- '#title' => t('Maximum file size per upload'),
- '#default_value' => variable_get('blogapi_uploadsize_' . $rid, $blogapi_uploadsize_default),
- '#size' => 5,
- '#maxlength' => 5,
- '#description' => t('The maximum size of a file a user can upload (in megabytes).'),
- );
- $form['settings_role_' . $rid]['blogapi_usersize_' . $rid] = array(
- '#type' => 'textfield',
- '#title' => t('Total file size per user'),
- '#default_value' => variable_get('blogapi_usersize_' . $rid, $blogapi_usersize_default),
- '#size' => 5,
- '#maxlength' => 5,
- '#description' => t('The maximum size of all files a user can have on the site (in megabytes).'),
- );
- }
-
- return system_settings_form($form, FALSE);
-}
-
-/**
- * Implement 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;
-}
-
-/**
* Implement 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 5 Jun 2009 21:45:39 -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 5 Jun 2009 21:45:40 -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 5 Jun 2009 21:45:40 -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 5 Jun 2009 21:45:38 -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;
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:45:38 -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 5 Jun 2009 21:45:38 -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.494
diff -u -p -r1.494 book.module
--- modules/book/book.module 27 May 2009 18:33:55 -0000 1.494
+++ modules/book/book.module 5 Jun 2009 21:45:38 -0000
@@ -7,60 +7,6 @@
*/
/**
- * Implement 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',
- ),
- );
-}
-
-/**
- * Implement 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
}
/**
- * Implement 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() {
}
/**
- * Implement 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;
-}
-
-/**
* Implement 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 = '') {
}
/**
- * Implement 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;
-}
-
-/**
- * Implement 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) {
}
/**
- * Implement 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;
- }
-}
-
-/**
- * Implement 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);
- }
-}
-
-/**
- * Implement 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);
- }
-}
-
-/**
- * Implement 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();
- }
-}
-
-/**
- * Implement 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) {
}
/**
- * Implement 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;
- }
-}
-
-/**
* Implement 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 5 Jun 2009 21:45:38 -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;
+ }
+}
+
+/**
+ * Implement 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);
+ }
+}
+
+/**
+ * Implement 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);
+ }
+}
+
+/**
+ * Implement 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();
+ }
+}
+
+/**
+ * Implement 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);
+ }
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:45:37 -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;
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:45:37 -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 5 Jun 2009 21:45:46 -0000
@@ -0,0 +1,229 @@
+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';
+ }
+ }
+}
+
+/**
+ * Implement hook_form_FORM_ID_alter().
+ */
+function color_form_system_themes_alter(&$form, &$form_state) {
+ _color_theme_select_form_alter($form, $form_state);
+}
+
+/**
+ * Implement hook_form_FORM_ID_alter().
+ */
+function color_form_system_theme_select_form_alter(&$form, &$form_state) {
+ _color_theme_select_form_alter($form, $form_state);
+}
+
+/**
+ * Form callback. Returns the configuration form.
+ */
+function color_scheme_form(&$form_state, $theme) {
+ $base = drupal_get_path('module', 'color');
+ $info = color_get_info($theme);
+
+ // Add Farbtastic color picker.
+ drupal_add_css('misc/farbtastic/farbtastic.css', array('preprocess' => FALSE));
+ drupal_add_js('misc/farbtastic/farbtastic.js', array('weight' => JS_LIBRARY));
+
+ // Add custom CSS and JS.
+ drupal_add_css($base . '/color.css', array('preprocess' => FALSE));
+ drupal_add_js($base . '/color.js');
+ drupal_add_js(array('color' => array(
+ 'reference' => color_get_palette($theme, TRUE)
+ )), 'setting');
+
+ // See if we're using a predefined scheme.
+ $current = implode(',', variable_get('color_' . $theme . '_palette', array()));
+ // Note: we use the original theme when the default scheme is chosen.
+ $current = isset($info['schemes'][$current]) ? $current : ($current == '' ? reset($info['schemes']) : '');
+
+ // Add scheme selector.
+ $info['schemes'][''] = t('Custom');
+ $form['scheme'] = array(
+ '#type' => 'select',
+ '#title' => t('Color set'),
+ '#options' => $info['schemes'],
+ '#default_value' => $current,
+ );
+
+ // Add palette fields.
+ $palette = color_get_palette($theme);
+ $names = array(
+ 'base' => t('Base color'),
+ 'link' => t('Link color'),
+ 'top' => t('Header top'),
+ 'bottom' => t('Header bottom'),
+ 'text' => t('Text color'),
+ );
+ $form['palette']['#tree'] = TRUE;
+ foreach ($palette as $name => $value) {
+ $form['palette'][$name] = array(
+ '#type' => 'textfield',
+ '#title' => $names[$name],
+ '#default_value' => $value,
+ '#size' => 8,
+ );
+ }
+ $form['theme'] = array('#type' => 'value', '#value' => arg(4));
+ $form['info'] = array('#type' => 'value', '#value' => $info);
+
+ return $form;
+}
+
+/**
+ * Submit handler for color change form.
+ */
+function color_scheme_form_submit($form, &$form_state) {
+ // Get theme coloring info.
+ if (!isset($form_state['values']['info'])) {
+ return;
+ }
+ $theme = $form_state['values']['theme'];
+ $info = $form_state['values']['info'];
+
+ // Resolve palette.
+ $palette = $form_state['values']['palette'];
+ if ($form_state['values']['scheme'] != '') {
+ $scheme = explode(',', $form_state['values']['scheme']);
+ foreach ($palette as $k => $color) {
+ $palette[$k] = array_shift($scheme);
+ }
+ }
+
+ // Make sure enough memory is available, if PHP's memory limit is compiled in.
+ if (function_exists('memory_get_usage')) {
+ // Fetch source image dimensions.
+ $source = drupal_get_path('theme', $theme) . '/' . $info['base_image'];
+ list($width, $height) = getimagesize($source);
+
+ // We need at least a copy of the source and a target buffer of the same
+ // size (both at 32bpp).
+ $required = $width * $height * 8;
+ $usage = memory_get_usage();
+ $limit = parse_size(ini_get('memory_limit'));
+ if ($usage + $required > $limit) {
+ drupal_set_message(t('There is not enough memory available to PHP to change this theme\'s color scheme. You need at least %size more. Check the PHP documentation for more information.', array('%size' => format_size($usage + $required - $limit), '@url' => 'http://www.php.net/manual/ini.core.php#ini.sect.resource-limits')), 'error');
+ return;
+ }
+ }
+
+ // Delete old files.
+ foreach (variable_get('color_' . $theme . '_files', array()) as $file) {
+ @unlink($file);
+ }
+ if (isset($file) && $file = dirname($file)) {
+ @rmdir($file);
+ }
+
+ // Don't render the default colorscheme, use the standard theme instead.
+ if (implode(',', color_get_palette($theme, TRUE)) == implode(',', $palette)
+ || $form_state['values']['op'] == t('Reset to defaults')) {
+ variable_del('color_' . $theme . '_palette');
+ variable_del('color_' . $theme . '_stylesheets');
+ variable_del('color_' . $theme . '_logo');
+ variable_del('color_' . $theme . '_files');
+ variable_del('color_' . $theme . '_screenshot');
+ return;
+ }
+
+ // Prepare target locations for generated files.
+ $id = $theme . '-' . substr(md5(serialize($palette) . microtime()), 0, 8);
+ $paths['color'] = file_directory_path() . '/color';
+ $paths['target'] = $paths['color'] . '/' . $id;
+ foreach ($paths as $path) {
+ file_check_directory($path, FILE_CREATE_DIRECTORY);
+ }
+ $paths['target'] = $paths['target'] . '/';
+ $paths['id'] = $id;
+ $paths['source'] = drupal_get_path('theme', $theme) . '/';
+ $paths['files'] = $paths['map'] = array();
+
+ // Save palette and logo location.
+ variable_set('color_' . $theme . '_palette', $palette);
+ variable_set('color_' . $theme . '_logo', $paths['target'] . 'logo.png');
+
+ // Copy over neutral images.
+ foreach ($info['copy'] as $file) {
+ $base = basename($file);
+ $source = $paths['source'] . $file;
+ $filepath = file_unmanaged_copy($source, $paths['target'] . $base);
+ $paths['map'][$file] = $base;
+ $paths['files'][] = $filepath;
+ }
+
+ // Render new images, if image has been provided.
+ if ($info['base_image']) {
+ _color_render_images($theme, $info, $paths, $palette);
+ }
+
+ // Rewrite theme stylesheets.
+ $css = array();
+ foreach ($info['css'] as $stylesheet) {
+ // Build a temporary array with LTR and RTL files.
+ $files = array();
+ if (file_exists($paths['source'] . $stylesheet)) {
+ $files[] = $stylesheet;
+
+ $rtl_file = str_replace('.css', '-rtl.css', $stylesheet);
+ if (file_exists($paths['source'] . $rtl_file)) {
+ $files[] = $rtl_file;
+ }
+ }
+
+ foreach ($files as $file) {
+ // Aggregate @imports recursively for each configured top level CSS file
+ // without optimization. Aggregation and optimization will be
+ // handled by drupal_build_css_cache() only.
+ $style = drupal_load_stylesheet($paths['source'] . $file, FALSE);
+
+ // Return the path to where this CSS file originated from, stripping
+ // off the name of the file at the end of the path.
+ $base = base_path() . dirname($paths['source'] . $file) . '/';
+ _drupal_build_css_path(NULL, $base);
+
+ // Prefix all paths within this CSS file, ignoring absolute paths.
+ $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $style);
+
+ // Rewrite stylesheet with new colors.
+ $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
+ $base_file = basename($file);
+ $css[] = $paths['target'] . $base_file;
+ _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
+ }
+ }
+
+ // Maintain list of files.
+ variable_set('color_' . $theme . '_stylesheets', $css);
+ variable_set('color_' . $theme . '_files', $paths['files']);
+}
+
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 5 Jun 2009 21:45:36 -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.59
diff -u -p -r1.59 color.module
--- modules/color/color.module 27 May 2009 18:33:55 -0000 1.59
+++ modules/color/color.module 5 Jun 2009 21:45:46 -0000
@@ -17,55 +17,6 @@ function color_help($path, $arg) {
}
/**
- * Implement hook_theme().
- */
-function color_theme() {
- return array(
- 'color_scheme_form' => array(
- 'arguments' => array('form' => NULL),
- ),
- );
-}
-
-/**
- * Implement 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';
- }
- }
-}
-
-/**
- * Implement hook_form_FORM_ID_alter().
- */
-function color_form_system_themes_alter(&$form, &$form_state) {
- _color_theme_select_form_alter($form, $form_state);
-}
-
-/**
- * Implement 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) {
@@ -162,62 +113,6 @@ function color_get_palette($theme, $defa
}
/**
- * Form callback. Returns the configuration form.
- */
-function color_scheme_form(&$form_state, $theme) {
- $base = drupal_get_path('module', 'color');
- $info = color_get_info($theme);
-
- // Add Farbtastic color picker.
- drupal_add_css('misc/farbtastic/farbtastic.css', array('preprocess' => FALSE));
- drupal_add_js('misc/farbtastic/farbtastic.js', array('weight' => JS_LIBRARY));
-
- // Add custom CSS and JS.
- drupal_add_css($base . '/color.css', array('preprocess' => FALSE));
- drupal_add_js($base . '/color.js');
- drupal_add_js(array('color' => array(
- 'reference' => color_get_palette($theme, TRUE)
- )), 'setting');
-
- // See if we're using a predefined scheme.
- $current = implode(',', variable_get('color_' . $theme . '_palette', array()));
- // Note: we use the original theme when the default scheme is chosen.
- $current = isset($info['schemes'][$current]) ? $current : ($current == '' ? reset($info['schemes']) : '');
-
- // Add scheme selector.
- $info['schemes'][''] = t('Custom');
- $form['scheme'] = array(
- '#type' => 'select',
- '#title' => t('Color set'),
- '#options' => $info['schemes'],
- '#default_value' => $current,
- );
-
- // Add palette fields.
- $palette = color_get_palette($theme);
- $names = array(
- 'base' => t('Base color'),
- 'link' => t('Link color'),
- 'top' => t('Header top'),
- 'bottom' => t('Header bottom'),
- 'text' => t('Text color'),
- );
- $form['palette']['#tree'] = TRUE;
- foreach ($palette as $name => $value) {
- $form['palette'][$name] = array(
- '#type' => 'textfield',
- '#title' => $names[$name],
- '#default_value' => $value,
- '#size' => 8,
- );
- }
- $form['theme'] = array('#type' => 'value', '#value' => arg(4));
- $form['info'] = array('#type' => 'value', '#value' => $info);
-
- return $form;
-}
-
-/**
* Theme the color form.
*
* @ingroup themeable
@@ -249,133 +144,6 @@ function theme_color_scheme_form($form)
}
/**
- * Submit handler for color change form.
- */
-function color_scheme_form_submit($form, &$form_state) {
- // Get theme coloring info.
- if (!isset($form_state['values']['info'])) {
- return;
- }
- $theme = $form_state['values']['theme'];
- $info = $form_state['values']['info'];
-
- // Resolve palette.
- $palette = $form_state['values']['palette'];
- if ($form_state['values']['scheme'] != '') {
- $scheme = explode(',', $form_state['values']['scheme']);
- foreach ($palette as $k => $color) {
- $palette[$k] = array_shift($scheme);
- }
- }
-
- // Make sure enough memory is available, if PHP's memory limit is compiled in.
- if (function_exists('memory_get_usage')) {
- // Fetch source image dimensions.
- $source = drupal_get_path('theme', $theme) . '/' . $info['base_image'];
- list($width, $height) = getimagesize($source);
-
- // We need at least a copy of the source and a target buffer of the same
- // size (both at 32bpp).
- $required = $width * $height * 8;
- $usage = memory_get_usage();
- $limit = parse_size(ini_get('memory_limit'));
- if ($usage + $required > $limit) {
- drupal_set_message(t('There is not enough memory available to PHP to change this theme\'s color scheme. You need at least %size more. Check the PHP documentation for more information.', array('%size' => format_size($usage + $required - $limit), '@url' => 'http://www.php.net/manual/ini.core.php#ini.sect.resource-limits')), 'error');
- return;
- }
- }
-
- // Delete old files.
- foreach (variable_get('color_' . $theme . '_files', array()) as $file) {
- @unlink($file);
- }
- if (isset($file) && $file = dirname($file)) {
- @rmdir($file);
- }
-
- // Don't render the default colorscheme, use the standard theme instead.
- if (implode(',', color_get_palette($theme, TRUE)) == implode(',', $palette)
- || $form_state['values']['op'] == t('Reset to defaults')) {
- variable_del('color_' . $theme . '_palette');
- variable_del('color_' . $theme . '_stylesheets');
- variable_del('color_' . $theme . '_logo');
- variable_del('color_' . $theme . '_files');
- variable_del('color_' . $theme . '_screenshot');
- return;
- }
-
- // Prepare target locations for generated files.
- $id = $theme . '-' . substr(md5(serialize($palette) . microtime()), 0, 8);
- $paths['color'] = file_directory_path() . '/color';
- $paths['target'] = $paths['color'] . '/' . $id;
- foreach ($paths as $path) {
- file_check_directory($path, FILE_CREATE_DIRECTORY);
- }
- $paths['target'] = $paths['target'] . '/';
- $paths['id'] = $id;
- $paths['source'] = drupal_get_path('theme', $theme) . '/';
- $paths['files'] = $paths['map'] = array();
-
- // Save palette and logo location.
- variable_set('color_' . $theme . '_palette', $palette);
- variable_set('color_' . $theme . '_logo', $paths['target'] . 'logo.png');
-
- // Copy over neutral images.
- foreach ($info['copy'] as $file) {
- $base = basename($file);
- $source = $paths['source'] . $file;
- $filepath = file_unmanaged_copy($source, $paths['target'] . $base);
- $paths['map'][$file] = $base;
- $paths['files'][] = $filepath;
- }
-
- // Render new images, if image has been provided.
- if ($info['base_image']) {
- _color_render_images($theme, $info, $paths, $palette);
- }
-
- // Rewrite theme stylesheets.
- $css = array();
- foreach ($info['css'] as $stylesheet) {
- // Build a temporary array with LTR and RTL files.
- $files = array();
- if (file_exists($paths['source'] . $stylesheet)) {
- $files[] = $stylesheet;
-
- $rtl_file = str_replace('.css', '-rtl.css', $stylesheet);
- if (file_exists($paths['source'] . $rtl_file)) {
- $files[] = $rtl_file;
- }
- }
-
- foreach ($files as $file) {
- // Aggregate @imports recursively for each configured top level CSS file
- // without optimization. Aggregation and optimization will be
- // handled by drupal_build_css_cache() only.
- $style = drupal_load_stylesheet($paths['source'] . $file, FALSE);
-
- // Return the path to where this CSS file originated from, stripping
- // off the name of the file at the end of the path.
- $base = base_path() . dirname($paths['source'] . $file) . '/';
- _drupal_build_css_path(NULL, $base);
-
- // Prefix all paths within this CSS file, ignoring absolute paths.
- $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', '_drupal_build_css_path', $style);
-
- // Rewrite stylesheet with new colors.
- $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
- $base_file = basename($file);
- $css[] = $paths['target'] . $base_file;
- _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
- }
- }
-
- // Maintain list of files.
- variable_set('color_' . $theme . '_stylesheets', $css);
- variable_set('color_' . $theme . '_files', $paths['files']);
-}
-
-/**
* Rewrite the stylesheet to match the colors in the palette.
*/
function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
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 5 Jun 2009 21:45:36 -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 5 Jun 2009 21:45:33 -0000
@@ -0,0 +1,80 @@
+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']));
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:45:34 -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;
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:45:47 -0000
@@ -0,0 +1,490 @@
+ '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')),
+ );
+ }
+}
+
+/**
+ * Generate the basic commenting form, for appending to a node or display on a separate page.
+ *
+ * @param $title
+ * Not used.
+ * @ingroup forms
+ * @see comment_form_validate()
+ * @see comment_form_submit()
+ */
+function comment_form(&$form_state, $edit, $title = NULL) {
+ global $user;
+ $op = isset($_POST['op']) ? $_POST['op'] : '';
+ $node = node_load($edit['nid']);
+
+ if (!$user->uid && variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) != COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
+ drupal_add_js(drupal_get_path('module', 'comment') . '/comment.js');
+ }
+ $edit += array('name' => '', 'mail' => '', 'homepage' => '');
+
+ if ($user->uid) {
+ if (!empty($edit['cid']) && user_access('administer comments')) {
+ if (!empty($edit['author'])) {
+ $author = $edit['author'];
+ }
+ elseif (!empty($edit['name'])) {
+ $author = $edit['name'];
+ }
+ else {
+ $author = $edit['registered_name'];
+ }
+
+ if (!empty($edit['status'])) {
+ $status = $edit['status'];
+ }
+ else {
+ $status = 0;
+ }
+
+ if (!empty($edit['date'])) {
+ $date = $edit['date'];
+ }
+ else {
+ $date = format_date($edit['timestamp'], 'custom', 'Y-m-d H:i O');
+ }
+
+ $form['admin'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Administration'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#weight' => -2,
+ );
+
+ if ($edit['registered_name'] != '') {
+ // The comment is by a registered user.
+ $form['admin']['author'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Authored by'),
+ '#size' => 30,
+ '#maxlength' => 60,
+ '#autocomplete_path' => 'user/autocomplete',
+ '#default_value' => $author,
+ '#weight' => -1,
+ );
+ }
+ else {
+ // The comment is by an anonymous user.
+ $form['is_anonymous'] = array(
+ '#type' => 'value',
+ '#value' => TRUE,
+ );
+ $form['admin']['name'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Authored by'),
+ '#size' => 30,
+ '#maxlength' => 60,
+ '#default_value' => $author,
+ '#weight' => -1,
+ );
+ $form['admin']['mail'] = array(
+ '#type' => 'textfield',
+ '#title' => t('E-mail'),
+ '#maxlength' => 64,
+ '#size' => 30,
+ '#default_value' => $edit['mail'],
+ '#description' => t('The content of this field is kept private and will not be shown publicly.'),
+ );
+ $form['admin']['homepage'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Homepage'),
+ '#maxlength' => 255,
+ '#size' => 30,
+ '#default_value' => $edit['homepage'],
+ );
+ }
+ $form['admin']['date'] = array(
+ '#type' => 'textfield',
+ '#parents' => array('date'),
+ '#title' => t('Authored on'),
+ '#size' => 20,
+ '#maxlength' => 25,
+ '#default_value' => $date,
+ '#weight' => -1,
+ );
+ $form['admin']['status'] = array(
+ '#type' => 'radios',
+ '#parents' => array('status'),
+ '#title' => t('Status'),
+ '#default_value' => $status,
+ '#options' => array(t('Not published'), t('Published')),
+ '#weight' => -1,
+ );
+ }
+ else {
+ $form['_author'] = array(
+ '#type' => 'item',
+ '#title' => t('Your name'),
+ '#markup' => theme('username', $user),
+ );
+ $form['author'] = array(
+ '#type' => 'value',
+ '#value' => $user->name,
+ );
+ }
+ }
+ elseif (variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MAY_CONTACT) {
+ $form['name'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Your name'),
+ '#maxlength' => 60,
+ '#size' => 30,
+ '#default_value' => $edit['name'] ? $edit['name'] : variable_get('anonymous', t('Anonymous')),
+ );
+ $form['mail'] = array(
+ '#type' => 'textfield',
+ '#title' => t('E-mail'),
+ '#maxlength' => 64,
+ '#size' => 30,
+ '#default_value' => $edit['mail'], '#description' => t('The content of this field is kept private and will not be shown publicly.'),
+ );
+ $form['homepage'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Homepage'),
+ '#maxlength' => 255,
+ '#size' => 30,
+ '#default_value' => $edit['homepage'],
+ );
+ }
+ elseif (variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MUST_CONTACT) {
+ $form['name'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Your name'),
+ '#maxlength' => 60,
+ '#size' => 30,
+ '#default_value' => $edit['name'] ? $edit['name'] : variable_get('anonymous', t('Anonymous')),
+ '#required' => TRUE,
+ );
+ $form['mail'] = array(
+ '#type' => 'textfield',
+ '#title' => t('E-mail'),
+ '#maxlength' => 64,
+ '#size' => 30,
+ '#default_value' => $edit['mail'], '#description' => t('The content of this field is kept private and will not be shown publicly.'),
+ '#required' => TRUE,
+ );
+ $form['homepage'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Homepage'),
+ '#maxlength' => 255,
+ '#size' => 30,
+ '#default_value' => $edit['homepage'],
+ );
+ }
+
+ if (variable_get('comment_subject_field_' . $node->type, 1) == 1) {
+ $form['subject'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Subject'),
+ '#maxlength' => 64,
+ '#default_value' => !empty($edit['subject']) ? $edit['subject'] : '',
+ );
+ }
+
+ if (!empty($edit['comment'])) {
+ $default = $edit['comment'];
+ }
+ else {
+ $default = '';
+ }
+
+ $form['comment'] = array(
+ '#type' => 'textarea',
+ '#title' => t('Comment'),
+ '#rows' => 15,
+ '#default_value' => $default,
+ '#text_format' => isset($edit['format']) ? $edit['format'] : FILTER_FORMAT_DEFAULT,
+ '#required' => TRUE,
+ );
+
+ $form['cid'] = array(
+ '#type' => 'value',
+ '#value' => !empty($edit['cid']) ? $edit['cid'] : NULL,
+ );
+ $form['pid'] = array(
+ '#type' => 'value',
+ '#value' => !empty($edit['pid']) ? $edit['pid'] : NULL,
+ );
+ $form['nid'] = array(
+ '#type' => 'value',
+ '#value' => $edit['nid'],
+ );
+ $form['uid'] = array(
+ '#type' => 'value',
+ '#value' => !empty($edit['uid']) ? $edit['uid'] : 0,
+ );
+
+ // Only show the save button if comment previews are optional or if we are
+ // already previewing the submission. However, if there are form errors,
+ // we hide the save button no matter what, so that optional form elements
+ // (e.g., captchas) can be updated.
+ if (!form_get_errors() && ((variable_get('comment_preview_' . $node->type, COMMENT_PREVIEW_REQUIRED) == COMMENT_PREVIEW_OPTIONAL) || ($op == t('Preview')) || ($op == t('Save')))) {
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save'),
+ '#weight' => 19,
+ );
+ }
+ $form['preview'] = array(
+ '#type' => 'button',
+ '#value' => t('Preview'),
+ '#weight' => 20,
+ );
+ $form['#token'] = 'comment' . $edit['nid'] . (isset($edit['pid']) ? $edit['pid'] : '');
+
+ if ($op == t('Preview')) {
+ $form['#after_build'] = array('comment_form_add_preview');
+ }
+
+ if (empty($edit['cid']) && empty($edit['pid'])) {
+ $form['#action'] = url('comment/reply/' . $edit['nid']);
+ }
+
+ return $form;
+}
+
+/**
+ * Validate comment form submissions.
+ */
+function comment_form_validate($form, &$form_state) {
+ global $user;
+ if ($user->uid === 0) {
+ foreach (array('name', 'homepage', 'mail') as $field) {
+ // Set cookie for 365 days.
+ if (isset($form_state['values'][$field])) {
+ setcookie('comment_info_' . $field, $form_state['values'][$field], REQUEST_TIME + 31536000, '/');
+ }
+ }
+ }
+ comment_validate($form_state['values']);
+}
+
+/**
+ * Validate comment data.
+ *
+ * @param $edit
+ * An associative array containing the comment data.
+ * @return
+ * The original $edit.
+ */
+function comment_validate($edit) {
+ global $user;
+
+ // Invoke other validation handlers.
+ comment_invoke_comment($edit, 'validate');
+
+ if (isset($edit['date'])) {
+ if (strtotime($edit['date']) === FALSE) {
+ form_set_error('date', t('You have to specify a valid date.'));
+ }
+ }
+ if (isset($edit['author']) && !$account = user_load_by_name($edit['author'])) {
+ form_set_error('author', t('You have to specify a valid author.'));
+ }
+
+ // Check validity of name, mail and homepage (if given).
+ if (!$user->uid || isset($edit['is_anonymous'])) {
+ $node = node_load($edit['nid']);
+ if (variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) > COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
+ if ($edit['name']) {
+ $query = db_select('users', 'u');
+ $query->addField('u', 'uid', 'uid');
+ $taken = $query->where('LOWER(name) = :name', array(':name' => $edit['name']))
+ ->countQuery()
+ ->execute()
+ ->fetchField();
+ if ($taken != 0) {
+ form_set_error('name', t('The name you used belongs to a registered user.'));
+ }
+ }
+ elseif (variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MUST_CONTACT) {
+ form_set_error('name', t('You have to leave your name.'));
+ }
+
+ if ($edit['mail']) {
+ if (!valid_email_address($edit['mail'])) {
+ form_set_error('mail', t('The e-mail address you specified is not valid.'));
+ }
+ }
+ elseif (variable_get('comment_anonymous_' . $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) == COMMENT_ANONYMOUS_MUST_CONTACT) {
+ form_set_error('mail', t('You have to leave an e-mail address.'));
+ }
+
+ if ($edit['homepage']) {
+ if (!valid_url($edit['homepage'], TRUE)) {
+ form_set_error('homepage', t('The URL of your homepage is not valid. Remember that it must be fully qualified, i.e. of the form http://example.com/directory.'));
+ }
+ }
+ }
+ }
+
+ return $edit;
+}
+
+/**
+ * Form builder; Generate and validate a comment preview form.
+ *
+ * @ingroup forms
+ */
+function comment_form_add_preview($form, &$form_state) {
+ global $user;
+ $edit = $form_state['values'];
+ drupal_set_title(t('Preview comment'), PASS_THROUGH);
+ $output = '';
+ $node = node_load($edit['nid']);
+
+ // Invoke full validation for the form, to protect against cross site
+ // request forgeries (CSRF) and setting arbitrary values for fields such as
+ // the text format. Preview the comment only when form validation does not
+ // set any errors.
+ drupal_validate_form($form['form_id']['#value'], $form, $form_state);
+ if (!form_get_errors()) {
+ _comment_form_submit($edit);
+ $comment = (object)$edit;
+ $comment->format = $comment->comment_format;
+
+ // Attach the user and time information.
+ if (!empty($edit['author'])) {
+ $account = user_load_by_name($edit['author']);
+ }
+ elseif ($user->uid && !isset($edit['is_anonymous'])) {
+ $account = $user;
+ }
+
+ if (!empty($account)) {
+ $comment->uid = $account->uid;
+ $comment->name = check_plain($account->name);
+ }
+ elseif (empty($comment->name)) {
+ $comment->name = variable_get('anonymous', t('Anonymous'));
+ }
+
+ $comment->timestamp = !empty($edit['timestamp']) ? $edit['timestamp'] : REQUEST_TIME;
+ $output .= theme('comment_view', $comment, $node);
+ }
+
+ $form['comment_preview'] = array(
+ '#markup' => $output,
+ '#weight' => -100,
+ '#prefix' => '
');
+ $build['system_actions_table'] = array('#markup' => theme('table', $header, $row));
+ }
+
+ if ($actions_map) {
+ $build['system_actions_manage_form'] = drupal_get_form('system_actions_manage_form', $options);
+ }
+
+ return $build;
+}
+
+/**
+ * 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, %term_name, %term_description, %term_id, %vocabulary_name, %vocabulary_description, %vocabulary_id. 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;
+}
+
+/**
+ * Implement 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));
+ }
+}
+
+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_type_get_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']);
+}
+
+/**
+ * Implement 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']);
+}
+
+/**
+ * Implement 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.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 5 Jun 2009 21:44:57 -0000
@@ -0,0 +1,76 @@
+ t('Main page content'),
+ // Cached elsewhere.
+ 'cache' => BLOCK_NO_CACHE,
+ );
+ $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;
+}
+
+/**
+ * Implement 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;
+ }
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:44:57 -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.file.inc
===================================================================
RCS file: modules/system/system.file.inc
diff -N modules/system/system.file.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.file.inc 5 Jun 2009 21:44:57 -0000
@@ -0,0 +1,19 @@
+ array(
+ 'title' => t('GD2 image manipulation toolkit'),
+ 'available' => drupal_function_exists('image_gd_check_settings') && image_gd_check_settings(),
+ ),
+ );
+}
Index: modules/system/system.form.inc
===================================================================
RCS file: modules/system/system.form.inc
diff -N modules/system/system.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.form.inc 5 Jun 2009 21:45:55 -0000
@@ -0,0 +1,42 @@
+ $value) {
+ if ($op == t('Reset to defaults')) {
+ variable_del($key);
+ }
+ else {
+ if (is_array($value) && isset($form_state['values']['array_filter'])) {
+ $value = array_keys(array_filter($value));
+ }
+ variable_set($key, $value);
+ }
+ }
+ if ($op == t('Reset to defaults')) {
+ drupal_set_message(t('The configuration options have been reset to their default values.'));
+ }
+ else {
+ drupal_set_message(t('The configuration options have been saved.'));
+ }
+
+ cache_clear_all();
+ drupal_theme_rebuild();
+}
+
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 5 Jun 2009 21:45:55 -0000
@@ -10,3 +10,11 @@ files[] = system.queue.inc
files[] = image.gd.inc
files[] = system.install
required = TRUE
+files[] = system.registry.inc
+files[] = system.actions.inc
+files[] = system.mail.inc
+files[] = system.user.inc
+files[] = system.block.inc
+files[] = system.cron.inc
+files[] = system.file.inc
+files[] = system.form.inc
Index: modules/system/system.mail.inc
===================================================================
RCS file: modules/system/system.mail.inc
diff -N modules/system/system.mail.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.mail.inc 5 Jun 2009 21:44:56 -0000
@@ -0,0 +1,49 @@
+ 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_type_get_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);
+}
+
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.708
diff -u -p -r1.708 system.module
--- modules/system/system.module 5 Jun 2009 05:28:28 -0000 1.708
+++ modules/system/system.module 5 Jun 2009 21:45:55 -0000
@@ -130,100 +130,6 @@ function system_help($path, $arg) {
}
/**
- * Implement hook_theme().
- */
-function system_theme() {
- return array_merge(drupal_common_theme(), array(
- 'system_theme_select_form' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'system_themes_form' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'system_modules_fieldset' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'system_modules_incompatible' => array(
- 'arguments' => array('message' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'system_modules_uninstall' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'status_report' => array(
- 'arguments' => array('requirements' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'admin_page' => array(
- 'arguments' => array('blocks' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'admin_block' => array(
- 'arguments' => array('block' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'admin_block_content' => array(
- 'arguments' => array('content' => NULL),
- 'file' => 'system.admin.inc',
- ),
- 'system_admin_by_module' => array(
- 'arguments' => array('menu_items' => NULL),
- 'file' => 'system.admin.inc',
- ),
- '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(),
- ));
-}
-
-/**
- * Implement 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.'),
- ),
- );
-}
-
-/**
* Implement hook_rdf_namespaces().
*/
function system_rdf_namespaces() {
@@ -243,552 +149,6 @@ function system_rdf_namespaces() {
}
/**
- * Implement hook_elements().
- */
-function system_elements() {
- // Top level form
- $type['form'] = array(
- '#method' => 'post',
- '#action' => request_uri(),
- '#theme_wrapper' => 'form',
- );
-
- $type['page'] = array(
- '#show_messages' => TRUE,
- '#show_blocks' => TRUE,
- '#theme' => 'page',
- );
-
- $type['list'] = array(
- '#title' => '',
- '#list_type' => 'ul',
- '#attributes' => array(),
- '#items' => array(),
- );
-
- /**
- * Input elements.
- */
- $type['submit'] = array(
- '#input' => TRUE,
- '#name' => 'op',
- '#button_type' => 'submit',
- '#executes_submit_callback' => TRUE,
- '#process' => array('form_process_ahah'),
- '#theme_wrapper' => 'button',
- );
-
- $type['button'] = array(
- '#input' => TRUE,
- '#name' => 'op',
- '#button_type' => 'submit',
- '#executes_submit_callback' => FALSE,
- '#process' => array('form_process_ahah'),
- '#theme_wrapper' => 'button',
- );
-
- $type['image_button'] = array(
- '#input' => TRUE,
- '#button_type' => 'submit',
- '#executes_submit_callback' => TRUE,
- '#process' => array('form_process_ahah'),
- '#return_value' => TRUE,
- '#has_garbage_value' => TRUE,
- '#src' => NULL,
- '#theme_wrapper' => 'image_button',
- );
-
- $type['textfield'] = array(
- '#input' => TRUE,
- '#size' => 60,
- '#maxlength' => 128,
- '#autocomplete_path' => FALSE,
- '#process' => array('form_process_text_format', 'form_process_ahah'),
- '#theme' => 'textfield',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['password'] = array(
- '#input' => TRUE,
- '#size' => 60,
- '#maxlength' => 128,
- '#process' => array('form_process_ahah'),
- '#theme' => 'password',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['password_confirm'] = array(
- '#input' => TRUE,
- '#process' => array('form_process_password_confirm'),
- '#theme_wrapper' => 'form_element',
- );
-
- $type['textarea'] = array(
- '#input' => TRUE,
- '#cols' => 60,
- '#rows' => 5,
- '#resizable' => TRUE,
- '#process' => array('form_process_text_format', 'form_process_ahah'),
- '#theme' => 'textarea',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['radios'] = array(
- '#input' => TRUE,
- '#process' => array('form_process_radios'),
- '#theme_wrapper' => 'radios',
- '#pre_render' => array('form_pre_render_conditional_form_element'),
- );
-
- $type['radio'] = array(
- '#input' => TRUE,
- '#default_value' => NULL,
- '#process' => array('form_process_ahah'),
- '#theme' => 'radio',
- '#theme_wrapper' => 'form_element',
- '#form_element_skip_title' => TRUE,
- );
-
- $type['checkboxes'] = array(
- '#input' => TRUE,
- '#tree' => TRUE,
- '#process' => array('form_process_checkboxes'),
- '#theme_wrapper' => 'checkboxes',
- '#pre_render' => array('form_pre_render_conditional_form_element'),
- );
-
- $type['checkbox'] = array(
- '#input' => TRUE,
- '#return_value' => 1,
- '#process' => array('form_process_ahah'),
- '#theme' => 'checkbox',
- '#theme_wrapper' => 'form_element',
- '#form_element_skip_title' => TRUE,
- );
-
- $type['select'] = array(
- '#input' => TRUE,
- '#size' => 0,
- '#multiple' => FALSE,
- '#process' => array('form_process_ahah'),
- '#theme' => 'select',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['weight'] = array(
- '#input' => TRUE,
- '#delta' => 10,
- '#default_value' => 0,
- '#process' => array('form_process_weight', 'form_process_ahah'),
- );
-
- $type['date'] = array(
- '#input' => TRUE,
- '#element_validate' => array('date_validate'),
- '#process' => array('form_process_date'),
- '#theme' => 'date',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['file'] = array(
- '#input' => TRUE,
- '#size' => 60,
- '#theme' => 'file',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['tableselect'] = array(
- '#input' => TRUE,
- '#js_select' => TRUE,
- '#multiple' => TRUE,
- '#process' => array('form_process_tableselect'),
- '#options' => array(),
- '#empty' => '',
- '#theme' => 'tableselect'
- );
-
- /**
- * Form structure.
- */
- $type['item'] = array(
- '#markup' => '',
- '#theme' => 'markup',
- '#theme_wrapper' => 'form_element',
- );
-
- $type['hidden'] = array(
- '#input' => TRUE,
- '#process' => array('form_process_ahah'),
- '#theme' => 'hidden',
- );
-
- $type['value'] = array(
- '#input' => TRUE,
- );
-
- $type['markup'] = array(
- '#markup' => '',
- '#theme' => 'markup',
- );
-
- $type['fieldset'] = array(
- '#collapsible' => FALSE,
- '#collapsed' => FALSE,
- '#value' => NULL,
- '#process' => array('form_process_fieldset', 'form_process_ahah'),
- '#pre_render' => array('form_pre_render_fieldset'),
- '#theme_wrapper' => 'fieldset',
- );
-
- $type['vertical_tabs'] = array(
- '#theme_wrapper' => 'vertical_tabs',
- '#default_tab' => '',
- '#process' => array('form_process_vertical_tabs'),
- );
-
- $type['token'] = array(
- '#input' => TRUE,
- '#theme' => array('hidden'),
- );
-
- return $type;
-}
-
-/**
- * Implement 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 callback' => 'system_admin_menu_block_access',
- 'access arguments' => array('admin/content', '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 callback' => 'system_admin_menu_block_access',
- 'access arguments' => array('admin/settings', '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 callback' => 'system_admin_menu_block_access',
- 'access arguments' => array('admin/build', '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,
- );
-
- // Development menu category.
- $items['admin/development'] = array(
- 'title' => 'Development',
- 'description' => 'Development tools.',
- 'position' => 'right',
- 'weight' => -7,
- 'page callback' => 'system_admin_menu_block_page',
- 'access callback' => 'system_admin_menu_block_access',
- 'access arguments' => array('admin/development', 'access administration pages'),
- );
-
- // 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 callback' => 'system_admin_menu_block_access',
- 'access arguments' => array('admin/reports', '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,
- );
- // 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
@@ -861,141 +221,6 @@ function system_preprocess_page(&$variab
}
/**
- * Implement 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;
- }
-}
-
-/**
- * Implement 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;
- }
-}
-
-/**
- * Implement 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');
- }
-}
-
-/**
- * Implement hook_block_list().
- */
-function system_block_list() {
- $blocks['main'] = array(
- 'info' => t('Main page content'),
- // Cached elsewhere.
- 'cache' => BLOCK_NO_CACHE,
- );
- $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;
-}
-
-/**
- * Implement 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;
- }
-}
-
-/**
- * Implement 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']);
- }
-}
-
-/**
* Implement hook_block_view().
*
* Generate a block with a promotional link to Drupal.org and
@@ -1451,40 +676,6 @@ function system_settings_form($form, $au
}
/**
- * Execute the system_settings_form.
- *
- * If you want node type configure style handling of your checkboxes,
- * add an array_filter value to your form.
- */
-function system_settings_form_submit($form, &$form_state) {
- $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
-
- // Exclude unnecessary elements.
- unset($form_state['values']['submit'], $form_state['values']['reset'], $form_state['values']['form_id'], $form_state['values']['op'], $form_state['values']['form_token'], $form_state['values']['form_build_id']);
-
- foreach ($form_state['values'] as $key => $value) {
- if ($op == t('Reset to defaults')) {
- variable_del($key);
- }
- else {
- if (is_array($value) && isset($form_state['values']['array_filter'])) {
- $value = array_keys(array_filter($value));
- }
- variable_set($key, $value);
- }
- }
- if ($op == t('Reset to defaults')) {
- drupal_set_message(t('The configuration options have been reset to their default values.'));
- }
- else {
- drupal_set_message(t('The configuration options have been saved.'));
- }
-
- cache_clear_all();
- drupal_theme_rebuild();
-}
-
-/**
* Helper function to sort requirements.
*/
function _system_sort_requirements($a, $b) {
@@ -1627,674 +818,6 @@ function system_get_module_admin_tasks($
}
/**
- * Implement 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();
-}
-
-/**
- * Implement hook_hook_info().
- */
-function system_hook_info() {
- return array(
- 'system' => array(
- 'cron' => array(
- 'run' => array(
- 'runs when' => t('When cron runs'),
- ),
- ),
- ),
- );
-}
-
-/**
- * Implement 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() {
- 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)
- ->orderByHeader($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'));
- }
- $build['system_actions_header'] = array('#markup' => '
' . t('Actions available to Drupal:') . '
');
- $build['system_actions_table'] = array('#markup' => theme('table', $header, $row));
- }
-
- if ($actions_map) {
- $build['system_actions_manage_form'] = drupal_get_form('system_actions_manage_form', $options);
- }
-
- return $build;
-}
-
-/**
- * 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, %term_name, %term_description, %term_id, %vocabulary_name, %vocabulary_description, %vocabulary_id. 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;
-}
-
-/**
- * Implement 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));
- }
-}
-
-/**
- * Implement 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_type_get_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_type_get_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']);
-}
-
-/**
- * Implement 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']);
-}
-
-/**
- * Implement 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
@@ -2394,14 +917,3 @@ function theme_meta_generator_header($ve
drupal_set_header('X-Generator', 'Drupal ' . $version . ' (http://drupal.org)');
}
-/**
- * Implement hook_image_toolkits().
- */
-function system_image_toolkits() {
- return array(
- 'gd' => array(
- 'title' => t('GD2 image manipulation toolkit'),
- 'available' => drupal_function_exists('image_gd_check_settings') && image_gd_check_settings(),
- ),
- );
-}
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 5 Jun 2009 21:44:55 -0000
@@ -0,0 +1,674 @@
+ '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 callback' => 'system_admin_menu_block_access',
+ 'access arguments' => array('admin/content', '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 callback' => 'system_admin_menu_block_access',
+ 'access arguments' => array('admin/settings', '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 callback' => 'system_admin_menu_block_access',
+ 'access arguments' => array('admin/build', '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,
+ );
+
+ // Development menu category.
+ $items['admin/development'] = array(
+ 'title' => 'Development',
+ 'description' => 'Development tools.',
+ 'position' => 'right',
+ 'weight' => -7,
+ 'page callback' => 'system_admin_menu_block_page',
+ 'access callback' => 'system_admin_menu_block_access',
+ 'access arguments' => array('admin/development', 'access administration pages'),
+ );
+
+ // 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 callback' => 'system_admin_menu_block_access',
+ 'access arguments' => array('admin/reports', '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,
+ );
+ // Default page for batch operations.
+ $items['batch'] = array(
+ 'page callback' => 'system_batch_page',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+ return $items;
+}
+
+/**
+ * Implement hook_theme().
+ */
+function system_theme() {
+ return array_merge(drupal_common_theme(), array(
+ 'system_theme_select_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'system_themes_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'system_modules_fieldset' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'system_modules_incompatible' => array(
+ 'arguments' => array('message' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'system_modules_uninstall' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'status_report' => array(
+ 'arguments' => array('requirements' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'admin_page' => array(
+ 'arguments' => array('blocks' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'admin_block' => array(
+ 'arguments' => array('block' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'admin_block_content' => array(
+ 'arguments' => array('content' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ 'system_admin_by_module' => array(
+ 'arguments' => array('menu_items' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
+ '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(),
+ ));
+}
+
+/**
+ * Implement hook_elements().
+ */
+function system_elements() {
+ // Top level form
+ $type['form'] = array(
+ '#method' => 'post',
+ '#action' => request_uri(),
+ '#theme_wrapper' => 'form',
+ );
+
+ $type['page'] = array(
+ '#show_messages' => TRUE,
+ '#show_blocks' => TRUE,
+ '#theme' => 'page',
+ );
+
+ $type['list'] = array(
+ '#title' => '',
+ '#list_type' => 'ul',
+ '#attributes' => array(),
+ '#items' => array(),
+ );
+
+ /**
+ * Input elements.
+ */
+ $type['submit'] = array(
+ '#input' => TRUE,
+ '#name' => 'op',
+ '#button_type' => 'submit',
+ '#executes_submit_callback' => TRUE,
+ '#process' => array('form_process_ahah'),
+ '#theme_wrapper' => 'button',
+ );
+
+ $type['button'] = array(
+ '#input' => TRUE,
+ '#name' => 'op',
+ '#button_type' => 'submit',
+ '#executes_submit_callback' => FALSE,
+ '#process' => array('form_process_ahah'),
+ '#theme_wrapper' => 'button',
+ );
+
+ $type['image_button'] = array(
+ '#input' => TRUE,
+ '#button_type' => 'submit',
+ '#executes_submit_callback' => TRUE,
+ '#process' => array('form_process_ahah'),
+ '#return_value' => TRUE,
+ '#has_garbage_value' => TRUE,
+ '#src' => NULL,
+ '#theme_wrapper' => 'image_button',
+ );
+
+ $type['textfield'] = array(
+ '#input' => TRUE,
+ '#size' => 60,
+ '#maxlength' => 128,
+ '#autocomplete_path' => FALSE,
+ '#process' => array('form_process_text_format', 'form_process_ahah'),
+ '#theme' => 'textfield',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['password'] = array(
+ '#input' => TRUE,
+ '#size' => 60,
+ '#maxlength' => 128,
+ '#process' => array('form_process_ahah'),
+ '#theme' => 'password',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['password_confirm'] = array(
+ '#input' => TRUE,
+ '#process' => array('form_process_password_confirm'),
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['textarea'] = array(
+ '#input' => TRUE,
+ '#cols' => 60,
+ '#rows' => 5,
+ '#resizable' => TRUE,
+ '#process' => array('form_process_text_format', 'form_process_ahah'),
+ '#theme' => 'textarea',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['radios'] = array(
+ '#input' => TRUE,
+ '#process' => array('form_process_radios'),
+ '#theme_wrapper' => 'radios',
+ '#pre_render' => array('form_pre_render_conditional_form_element'),
+ );
+
+ $type['radio'] = array(
+ '#input' => TRUE,
+ '#default_value' => NULL,
+ '#process' => array('form_process_ahah'),
+ '#theme' => 'radio',
+ '#theme_wrapper' => 'form_element',
+ '#form_element_skip_title' => TRUE,
+ );
+
+ $type['checkboxes'] = array(
+ '#input' => TRUE,
+ '#tree' => TRUE,
+ '#process' => array('form_process_checkboxes'),
+ '#theme_wrapper' => 'checkboxes',
+ '#pre_render' => array('form_pre_render_conditional_form_element'),
+ );
+
+ $type['checkbox'] = array(
+ '#input' => TRUE,
+ '#return_value' => 1,
+ '#process' => array('form_process_ahah'),
+ '#theme' => 'checkbox',
+ '#theme_wrapper' => 'form_element',
+ '#form_element_skip_title' => TRUE,
+ );
+
+ $type['select'] = array(
+ '#input' => TRUE,
+ '#size' => 0,
+ '#multiple' => FALSE,
+ '#process' => array('form_process_ahah'),
+ '#theme' => 'select',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['weight'] = array(
+ '#input' => TRUE,
+ '#delta' => 10,
+ '#default_value' => 0,
+ '#process' => array('form_process_weight', 'form_process_ahah'),
+ );
+
+ $type['date'] = array(
+ '#input' => TRUE,
+ '#element_validate' => array('date_validate'),
+ '#process' => array('form_process_date'),
+ '#theme' => 'date',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['file'] = array(
+ '#input' => TRUE,
+ '#size' => 60,
+ '#theme' => 'file',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['tableselect'] = array(
+ '#input' => TRUE,
+ '#js_select' => TRUE,
+ '#multiple' => TRUE,
+ '#process' => array('form_process_tableselect'),
+ '#options' => array(),
+ '#empty' => '',
+ '#theme' => 'tableselect'
+ );
+
+ /**
+ * Form structure.
+ */
+ $type['item'] = array(
+ '#markup' => '',
+ '#theme' => 'markup',
+ '#theme_wrapper' => 'form_element',
+ );
+
+ $type['hidden'] = array(
+ '#input' => TRUE,
+ '#process' => array('form_process_ahah'),
+ '#theme' => 'hidden',
+ );
+
+ $type['value'] = array(
+ '#input' => TRUE,
+ );
+
+ $type['markup'] = array(
+ '#markup' => '',
+ '#theme' => 'markup',
+ );
+
+ $type['fieldset'] = array(
+ '#collapsible' => FALSE,
+ '#collapsed' => FALSE,
+ '#value' => NULL,
+ '#process' => array('form_process_fieldset', 'form_process_ahah'),
+ '#pre_render' => array('form_pre_render_fieldset'),
+ '#theme_wrapper' => 'fieldset',
+ );
+
+ $type['vertical_tabs'] = array(
+ '#theme_wrapper' => 'vertical_tabs',
+ '#default_tab' => '',
+ '#process' => array('form_process_vertical_tabs'),
+ );
+
+ $type['token'] = array(
+ '#input' => TRUE,
+ '#theme' => array('hidden'),
+ );
+
+ return $type;
+}
+
+/**
+ * Implement hook_hook_info().
+ */
+function system_hook_info() {
+ return array(
+ 'system' => array(
+ 'cron' => array(
+ 'run' => array(
+ 'runs when' => t('When cron runs'),
+ ),
+ ),
+ ),
+ );
+}
+
+/**
+ * Implement 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'),
+ )
+ )
+ );
+}
+
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 5 Jun 2009 21:44:56 -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.'),
+ ),
+ );
+}
+
+/**
+ * Implement 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;
+ }
+}
+
+/**
+ * Implement 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;
+ }
+}
+
+/**
+ * Implement 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.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v
retrieving revision 1.53
diff -u -p -r1.53 taxonomy.admin.inc
--- modules/taxonomy/taxonomy.admin.inc 4 Jun 2009 03:33:29 -0000 1.53
+++ modules/taxonomy/taxonomy.admin.inc 5 Jun 2009 21:45:56 -0000
@@ -932,3 +932,10 @@ function taxonomy_vocabulary_confirm_res
watchdog('taxonomy', 'Reset vocabulary %name to alphabetical order.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
$form_state['redirect'] = 'admin/content/taxonomy/' . $form_state['values']['vid'];
}
+/**
+ * Return the vocabulary name given the vocabulary object.
+ */
+function taxonomy_admin_vocabulary_title_callback($vocabulary) {
+ return check_plain($vocabulary->name);
+}
+
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 5 Jun 2009 21:44:51 -0000
@@ -8,3 +8,6 @@ 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
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.477
diff -u -p -r1.477 taxonomy.module
--- modules/taxonomy/taxonomy.module 5 Jun 2009 05:23:57 -0000 1.477
+++ modules/taxonomy/taxonomy.module 5 Jun 2009 21:45:56 -0000
@@ -7,35 +7,6 @@
*/
/**
- * Implement hook_perm().
- */
-function taxonomy_perm() {
- return array(
- 'administer taxonomy' => array(
- 'title' => t('Administer taxonomy'),
- 'description' => t('Manage taxonomy vocabularies and terms.'),
- ),
- );
-}
-
-/**
- * Implement 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,104 +83,6 @@ function taxonomy_term_path($term) {
}
/**
- * Implement 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) {
- return check_plain($vocabulary->name);
-}
-
-/**
* Save a vocabulary given a vocabulary object.
*/
function taxonomy_vocabulary_save($vocabulary) {
@@ -773,111 +646,6 @@ function taxonomy_node_get_terms($node,
}
/**
- * Save term associations for a given node.
- */
-function taxonomy_node_save($node, $terms) {
-
- taxonomy_node_delete_revision($node);
-
- // Free tagging vocabularies do not send their tids in the form,
- // so we'll detect them here and process them independently.
- if (isset($terms['tags'])) {
- $typed_input = $terms['tags'];
- unset($terms['tags']);
-
- foreach ($typed_input as $vid => $vid_value) {
- $typed_terms = drupal_explode_tags($vid_value);
-
- $inserted = array();
- foreach ($typed_terms as $typed_term) {
- // See if the term exists in the chosen vocabulary
- // and return the tid; otherwise, add a new record.
- $possibilities = taxonomy_get_term_by_name($typed_term);
- $typed_term_tid = NULL; // tid match, if any.
- foreach ($possibilities as $possibility) {
- if ($possibility->vid == $vid) {
- $typed_term_tid = $possibility->tid;
- }
- }
-
- if (!$typed_term_tid) {
- $edit = array('vid' => $vid, 'name' => $typed_term);
- $term = (object)$edit;
- $status = taxonomy_term_save($term);
- $typed_term_tid = $term->tid;
- }
-
- // Defend against duplicate, differently cased tags
- if (!isset($inserted[$typed_term_tid])) {
- db_insert('taxonomy_term_node')
- ->fields(array(
- 'nid' => $node->nid,
- 'vid' => $node->vid,
- 'tid' => $typed_term_tid
- ))
- ->execute();
- $inserted[$typed_term_tid] = TRUE;
- }
- }
- }
- }
-
- if (is_array($terms) && !empty($terms)) {
- $query = db_insert('taxonomy_term_node')
- ->fields(array('nid', 'vid', 'tid'));
-
- foreach ($terms as $term) {
- if (is_array($term)) {
- foreach ($term as $tid) {
- if ($tid) {
- $query->values(array(
- 'nid' => $node->nid,
- 'vid' => $node->vid,
- 'tid' => $tid,
- ));
- }
- }
- }
- elseif (is_object($term)) {
- $query->values(array(
- 'nid' => $node->nid,
- 'vid' => $node->vid,
- 'tid' => $term->tid,
- ));
- }
- elseif ($term) {
- $query->values(array(
- 'nid' => $node->nid,
- 'vid' => $node->vid,
- 'tid' => $term,
- ));
- }
- }
- $query->execute();
- }
-}
-
-/**
- * Implement 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') {
@@ -1572,84 +1340,6 @@ function taxonomy_node_load($nodes) {
}
/**
- * Implement hook_node_insert().
- */
-function taxonomy_node_insert($node) {
- if (!empty($node->taxonomy)) {
- taxonomy_node_save($node, $node->taxonomy);
- }
-}
-
-/**
- * Implement hook_node_update().
- */
-function taxonomy_node_update($node) {
- if (!empty($node->taxonomy)) {
- taxonomy_node_save($node, $node->taxonomy);
- }
-}
-
-/**
- * Implement 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');
-}
-
-/**
- * Implement 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');
-}
-
-/**
- * Implement 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)));
- }
- }
- }
- }
-}
-
-/**
- * Implement hook_node_update_index().
- */
-function taxonomy_node_update_index($node) {
- $output = array();
- if (isset($node->taxonomy) && is_array($node->taxonomy)) {
- 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
@@ -1739,23 +1429,3 @@ function taxonomy_implode_tags($tags, $v
return implode(', ', $typed_tags);
}
-/**
- * Implement hook_hook_info().
- */
-function taxonomy_hook_info() {
- return array(
- 'taxonomy' => array(
- 'taxonomy' => array(
- 'insert' => array(
- 'runs when' => t('After saving a new term to the database'),
- ),
- 'update' => array(
- 'runs when' => t('After saving an updated term to the database'),
- ),
- 'delete' => array(
- 'runs when' => t('After deleting a term')
- ),
- ),
- ),
- );
-}
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 5 Jun 2009 21:45:56 -0000
@@ -0,0 +1,191 @@
+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');
+}
+
+/**
+ * Implement hook_node_insert().
+ */
+function taxonomy_node_insert($node) {
+ if (!empty($node->taxonomy)) {
+ taxonomy_node_save($node, $node->taxonomy);
+ }
+}
+
+/**
+ * Implement hook_node_update().
+ */
+function taxonomy_node_update($node) {
+ if (!empty($node->taxonomy)) {
+ taxonomy_node_save($node, $node->taxonomy);
+ }
+}
+
+/**
+ * Implement 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');
+}
+
+/**
+ * Implement 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');
+}
+
+/**
+ * Implement 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)));
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Implement hook_node_update_index().
+ */
+function taxonomy_node_update_index($node) {
+ $output = array();
+ if (isset($node->taxonomy) && is_array($node->taxonomy)) {
+ foreach ($node->taxonomy as $term) {
+ $output[] = $term->name;
+ }
+ }
+ if (count($output)) {
+ return '(' . implode(', ', $output) . ')';
+ }
+}
+
+/**
+ * Save term associations for a given node.
+ */
+function taxonomy_node_save($node, $terms) {
+
+ taxonomy_node_delete_revision($node);
+
+ // Free tagging vocabularies do not send their tids in the form,
+ // so we'll detect them here and process them independently.
+ if (isset($terms['tags'])) {
+ $typed_input = $terms['tags'];
+ unset($terms['tags']);
+
+ foreach ($typed_input as $vid => $vid_value) {
+ $typed_terms = drupal_explode_tags($vid_value);
+
+ $inserted = array();
+ foreach ($typed_terms as $typed_term) {
+ // See if the term exists in the chosen vocabulary
+ // and return the tid; otherwise, add a new record.
+ $possibilities = taxonomy_get_term_by_name($typed_term);
+ $typed_term_tid = NULL; // tid match, if any.
+ foreach ($possibilities as $possibility) {
+ if ($possibility->vid == $vid) {
+ $typed_term_tid = $possibility->tid;
+ }
+ }
+
+ if (!$typed_term_tid) {
+ $edit = array('vid' => $vid, 'name' => $typed_term);
+ $term = (object)$edit;
+ $status = taxonomy_term_save($term);
+ $typed_term_tid = $term->tid;
+ }
+
+ // Defend against duplicate, differently cased tags
+ if (!isset($inserted[$typed_term_tid])) {
+ db_insert('taxonomy_term_node')
+ ->fields(array(
+ 'nid' => $node->nid,
+ 'vid' => $node->vid,
+ 'tid' => $typed_term_tid
+ ))
+ ->execute();
+ $inserted[$typed_term_tid] = TRUE;
+ }
+ }
+ }
+ }
+
+ if (is_array($terms) && !empty($terms)) {
+ $query = db_insert('taxonomy_term_node')
+ ->fields(array('nid', 'vid', 'tid'));
+
+ foreach ($terms as $term) {
+ if (is_array($term)) {
+ foreach ($term as $tid) {
+ if ($tid) {
+ $query->values(array(
+ 'nid' => $node->nid,
+ 'vid' => $node->vid,
+ 'tid' => $tid,
+ ));
+ }
+ }
+ }
+ elseif (is_object($term)) {
+ $query->values(array(
+ 'nid' => $node->nid,
+ 'vid' => $node->vid,
+ 'tid' => $term->tid,
+ ));
+ }
+ elseif ($term) {
+ $query->values(array(
+ 'nid' => $node->nid,
+ 'vid' => $node->vid,
+ 'tid' => $term,
+ ));
+ }
+ }
+ $query->execute();
+ }
+}
+
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 5 Jun 2009 21:44:50 -0000
@@ -0,0 +1,136 @@
+ '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;
+}
+
+/**
+ * Implement 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()),
+ ),
+ );
+}
+
+/**
+ * Implement hook_hook_info().
+ */
+function taxonomy_hook_info() {
+ return array(
+ 'taxonomy' => array(
+ 'taxonomy' => array(
+ 'insert' => array(
+ 'runs when' => t('After saving a new term to the database'),
+ ),
+ 'update' => array(
+ 'runs when' => t('After saving an updated term to the database'),
+ ),
+ 'delete' => array(
+ 'runs when' => t('After deleting a term')
+ ),
+ ),
+ ),
+ );
+}
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 5 Jun 2009 21:44:51 -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 5 Jun 2009 21:44:49 -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.158
diff -u -p -r1.158 tracker.module
--- modules/tracker/tracker.module 27 May 2009 18:34:01 -0000 1.158
+++ modules/tracker/tracker.module 5 Jun 2009 21:44:49 -0000
@@ -20,43 +20,6 @@ function tracker_help($path, $arg) {
}
/**
- * Implement 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 5 Jun 2009 21:44:49 -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 5 Jun 2009 21:44:49 -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 5 Jun 2009 21:44:49 -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.46
diff -u -p -r1.46 translation.module
--- modules/translation/translation.module 27 May 2009 18:34:02 -0000 1.46
+++ modules/translation/translation.module 5 Jun 2009 21:44:49 -0000
@@ -51,23 +51,6 @@ function translation_help($path, $arg) {
}
/**
- * Implement 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)
}
/**
- * Implement hook_perm().
- */
-function translation_perm() {
- return array(
- 'translate content' => array(
- 'title' => t('Translate content'),
- 'description' => t('Translate website content.'),
- ),
- );
-}
-
-/**
- * Implement 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')));
-}
-
-/**
* Implement hook_form_alter().
*
* - Add translation option to content type form.
@@ -190,123 +151,6 @@ function translation_node_view($node, $t
}
/**
- * Implement 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);
- }
- }
-}
-
-/**
- * Implement 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();
- }
- }
-}
-
-/**
- * Implement 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();
- }
- }
- }
-}
-
-/**
- * Implement 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.'));
- }
- }
-}
-
-/**
- * Implement 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 5 Jun 2009 21:44:48 -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);
+ }
+ }
+}
+
+/**
+ * Implement 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();
+ }
+ }
+}
+
+/**
+ * Implement 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();
+ }
+ }
+ }
+}
+
+/**
+ * Implement 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.'));
+ }
+ }
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:44:48 -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 5 Jun 2009 21:44:48 -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 5 Jun 2009 21:44:47 -0000
@@ -0,0 +1,18 @@
+condition('aid', $aid)
+ ->execute();
+}
Index: modules/trigger/trigger.comment.inc
===================================================================
RCS file: modules/trigger/trigger.comment.inc
diff -N modules/trigger/trigger.comment.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/trigger/trigger.comment.inc 5 Jun 2009 21:44:47 -0000
@@ -0,0 +1,29 @@
+ 'cron',
+ 'op' => 'run',
+ );
+ // 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 5 Jun 2009 21:44:47 -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.38
diff -u -p -r1.38 trigger.module
--- modules/trigger/trigger.module 5 Jun 2009 15:41:05 -0000 1.38
+++ modules/trigger/trigger.module 5 Jun 2009 21:44:47 -0000
@@ -32,93 +32,6 @@ function trigger_help($path, $arg) {
}
/**
- * Implement 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_select('system')
- ->condition('name', $module)
- ->execute()
- ->fetchField();
- $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) {
@@ -144,18 +57,6 @@ function _trigger_get_hook_aids($hook, $
}
/**
- * Implement hook_theme().
- */
-function trigger_theme() {
- return array(
- 'trigger_display' => array(
- 'arguments' => array('element'),
- 'file' => 'trigger.admin.inc',
- ),
- );
-}
-
-/**
* Implement hook_forms(). We reuse code by using the
* same assignment form definition for each node-op combination.
*/
@@ -250,34 +151,6 @@ function trigger_node_view($node, $tease
}
/**
- * Implement hook_node_update().
- */
-function trigger_node_update($node) {
- _trigger_node($node, 'update');
-}
-
-/**
- * Implement hook_node_presave().
- */
-function trigger_node_presave($node) {
- _trigger_node($node, 'presave');
-}
-
-/**
- * Implement hook_node_insert().
- */
-function trigger_node_insert($node) {
- _trigger_node($node, 'insert');
-}
-
-/**
- * Implement 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
@@ -304,27 +177,6 @@ function _trigger_normalize_comment_cont
}
/**
- * Implement hook_comment_insert().
- */
-function trigger_comment_insert($form_values) {
- _trigger_comment($form_values, 'insert');
-}
-
-/**
- * Implement hook_comment_update().
- */
-function trigger_comment_update($form_values) {
- _trigger_comment($form_values, 'update');
-}
-
-/**
- * Implement hook_comment_delete().
- */
-function trigger_comment_delete($comment) {
- _trigger_comment($comment, 'delete');
-}
-
-/**
* Implement hook_comment_view().
*/
function trigger_comment_view($comment) {
@@ -369,20 +221,6 @@ function _trigger_comment($a1, $op) {
}
/**
- * Implement hook_cron().
- */
-function trigger_cron() {
- $aids = _trigger_get_hook_aids('cron', 'run');
- $context = array(
- 'hook' => 'cron',
- 'op' => 'run',
- );
- // 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
@@ -414,46 +252,6 @@ function _trigger_normalize_user_context
}
/**
- * trigger_user_login
- */
-function trigger_user_login(&$edit, &$account, $category) {
- _trigger_user('login', $edit, $account, $category);
-}
-
-/**
- * Implement hook_user_logout().
- */
-function trigger_user_logout($edit, $account) {
- _trigger_user('logout', $edit, $account);
-}
-
-/**
- * Implement hook_user_insert().
- */
-function trigger_user_insert(&$edit, &$account, $category) {
- _trigger_user('insert', $edit, $account, $category);
-}
-
-/**
- * Implement hook_user_update().
- */
-function trigger_user_update(&$edit, &$account, $category) {
- _trigger_user('update', $edit, $account, $category);
-}
-
-/**
- * Implement 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;
- }
-}
-
-/**
* Implement hook_user_view().
*/
function trigger_user_view(&$edit, &$account, $category) {
@@ -489,21 +287,6 @@ function _trigger_user($op, &$edit, &$ac
}
/**
- * Implement 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
- );
- actions_do(array_keys($aids), (object) $array, $context);
-}
-
-/**
* Often we generate a select field of all actions. This function
* generates the options for that select.
*
@@ -526,13 +309,3 @@ function trigger_options($type = 'all')
}
}
-/**
- * Implement hook_actions_delete().
- *
- * Remove all trigger entries for the given action, when deleted.
- */
-function trigger_actions_delete($aid) {
- db_delete('trigger_assignments')
- ->condition('aid', $aid)
- ->execute();
-}
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 5 Jun 2009 21:44:47 -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_select('system')
+ ->condition('name', $module)
+ ->execute()
+ ->fetchField();
+ $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;
+}
+
+/**
+ * Implement hook_theme().
+ */
+function trigger_theme() {
+ return array(
+ 'trigger_display' => array(
+ 'arguments' => array('element'),
+ 'file' => 'trigger.admin.inc',
+ ),
+ );
+}
+
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 5 Jun 2009 21:44:47 -0000
@@ -0,0 +1,23 @@
+ 'taxonomy',
+ 'op' => $op
+ );
+ actions_do(array_keys($aids), (object) $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 5 Jun 2009 21:44:47 -0000
@@ -0,0 +1,48 @@
+ 'textfield',
+ '#default_value' => $context['subject'],
+ );
+ return $form;
+}
+
+/**
+ * Form submission handler for configurable test action.
+ */
+function trigger_test_system_cron_conf_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(
+ 'subject' => $form_values['subject'],
+ );
+ return $params;
+}
Index: modules/trigger/tests/trigger_test.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/trigger/tests/trigger_test.info,v
retrieving revision 1.1
diff -u -p -r1.1 trigger_test.info
--- modules/trigger/tests/trigger_test.info 27 May 2009 16:29:05 -0000 1.1
+++ modules/trigger/tests/trigger_test.info 5 Jun 2009 21:44:47 -0000
@@ -5,3 +5,5 @@ package = Testing
core = 7.x
files[] = trigger_test.module
hidden = TRUE
+files[] = trigger_test.registry.inc
+files[] = trigger_test.actions.inc
Index: modules/trigger/tests/trigger_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/trigger/tests/trigger_test.module,v
retrieving revision 1.2
diff -u -p -r1.2 trigger_test.module
--- modules/trigger/tests/trigger_test.module 31 May 2009 03:12:19 -0000 1.2
+++ modules/trigger/tests/trigger_test.module 5 Jun 2009 21:44:47 -0000
@@ -6,71 +6,3 @@
* Mock module to aid in testing trigger.module.
*/
-/**
- * Implementation of hook_action_info().
- */
-function trigger_test_action_info() {
- // Register an action that can be assigned to the trigger "cron run".
- return array(
- 'trigger_test_system_cron_action' => array(
- 'type' => 'system',
- 'description' => t('Cron test action'),
- 'configurable' => FALSE,
- 'hooks' => array(
- 'cron' => array('run'),
- ),
- ),
- 'trigger_test_system_cron_conf_action' => array(
- 'type' => 'system',
- 'description' => t('Cron test configurable action'),
- 'configurable' => TRUE,
- 'hooks' => array(
- 'cron' => array('run'),
- ),
- ),
- );
-}
-
-/**
- * Action fired during the "cron run" trigger test.
- */
-function trigger_test_system_cron_action() {
- // Indicate successful execution by setting a persistent variable.
- variable_set('trigger_test_system_cron_action', TRUE);
-}
-
-/**
- * Implement a configurable Drupal action.
- */
-function trigger_test_system_cron_conf_action($object, $context) {
- // Indicate successful execution by incrementing a persistent variable.
- $value = variable_get('trigger_test_system_cron_conf_action', 0) + 1;
- variable_set('trigger_test_system_cron_conf_action', $value);
-}
-
-/**
- * Form for configurable test action.
- */
-function trigger_test_system_cron_conf_action_form($context) {
- if (!isset($context['subject'])) {
- $context['subject'] = '';
- }
- $form['subject'] = array(
- '#type' => 'textfield',
- '#default_value' => $context['subject'],
- );
- return $form;
-}
-
-/**
- * Form submission handler for configurable test action.
- */
-function trigger_test_system_cron_conf_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(
- 'subject' => $form_values['subject'],
- );
- return $params;
-}
Index: modules/trigger/tests/trigger_test.registry.inc
===================================================================
RCS file: modules/trigger/tests/trigger_test.registry.inc
diff -N modules/trigger/tests/trigger_test.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/trigger/tests/trigger_test.registry.inc 5 Jun 2009 21:44:47 -0000
@@ -0,0 +1,33 @@
+ array(
+ 'type' => 'system',
+ 'description' => t('Cron test action'),
+ 'configurable' => FALSE,
+ 'hooks' => array(
+ 'cron' => array('run'),
+ ),
+ ),
+ 'trigger_test_system_cron_conf_action' => array(
+ 'type' => 'system',
+ 'description' => t('Cron test configurable action'),
+ 'configurable' => TRUE,
+ 'hooks' => array(
+ 'cron' => array('run'),
+ ),
+ ),
+ );
+}
+
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 5 Jun 2009 21:44:46 -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 5 Jun 2009 21:44:46 -0000
@@ -0,0 +1,32 @@
+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.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/update/update.module,v
retrieving revision 1.35
diff -u -p -r1.35 update.module
--- modules/update/update.module 27 May 2009 18:34:02 -0000 1.35
+++ modules/update/update.module 5 Jun 2009 21:44:46 -0000
@@ -112,53 +112,6 @@ function update_help($path, $arg) {
}
/**
- * Implement hook_menu().
- */
-function update_menu() {
- $items = array();
-
- $items['admin/reports/updates'] = array(
- 'title' => '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;
-}
-
-/**
- * Implement 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),
- ),
- );
-}
-
-/**
* Implement hook_requirements().
*
* @return
@@ -272,44 +225,6 @@ function _update_requirement_check($proj
}
/**
- * Implement 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();
- }
-}
-
-/**
- * Implement 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';
-}
-
-/**
- * Implement 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() {
}
/**
- * Implement 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
}
/**
- * Implement 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 5 Jun 2009 21:44:46 -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;
+}
+
+/**
+ * Implement 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),
+ ),
+ );
+}
+
+/**
+ * Implement 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.file.inc
===================================================================
RCS file: modules/upload/upload.file.inc
diff -N modules/upload/upload.file.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.file.inc 5 Jun 2009 21:44:45 -0000
@@ -0,0 +1,46 @@
+ $filepath))->fetchObject();
+
+ if ($file && user_access('view uploaded files') && ($node = node_load($file->nid)) && node_access('view', $node)) {
+ return array(
+ 'Content-Type' => $file->filemime,
+ 'Content-Length' => $file->filesize,
+ );
+ }
+ else {
+ return -1;
+ }
+}
+
+/**
+ * Implement hook_file_references().
+ */
+function upload_file_references($file) {
+ // If upload.module is still using a file, do not let other modules delete it.
+ $file_used = (bool) db_query_range('SELECT 1 FROM {upload} WHERE fid = :fid', array(':fid' => $file->fid), 0, 1)->fetchField();
+ if ($file_used) {
+ // Return the name of the module and how many references it has to the file.
+ return array('upload' => $count);
+ }
+}
+
+/**
+ * Implement hook_file_delete().
+ */
+function upload_file_delete($file) {
+ // Delete all information associated with the file.
+ db_delete('upload')->condition('fid', $file->fid)->execute();
+}
+
Index: modules/upload/upload.form.inc
===================================================================
RCS file: modules/upload/upload.form.inc
diff -N modules/upload/upload.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.form.inc 5 Jun 2009 21:45:57 -0000
@@ -0,0 +1,54 @@
+ array($limits['extensions']),
+ 'file_validate_image_resolution' => array($limits['resolution']),
+ 'file_validate_size' => array($limits['file_size'], $limits['user_size']),
+ );
+
+ // Save new file uploads.
+ if (user_access('upload files') && ($file = file_save_upload('upload', $validators, file_directory_path()))) {
+ $file->list = variable_get('upload_list_default', 1);
+ $file->description = $file->filename;
+ $file->weight = 0;
+ $file->new = TRUE;
+ $form['#node']->files[$file->fid] = $file;
+ $form_state['values']['files'][$file->fid] = (array)$file;
+ }
+
+ if (isset($form_state['values']['files'])) {
+ foreach ($form_state['values']['files'] as $fid => $file) {
+ $form_state['values']['files'][$fid]['new'] = !empty($form['#node']->files[$fid]->new);
+ }
+ }
+
+ // Order the form according to the set file weight values.
+ if (!empty($form_state['values']['files'])) {
+ $microweight = 0.001;
+ foreach ($form_state['values']['files'] as $fid => $file) {
+ if (is_numeric($fid)) {
+ $form_state['values']['files'][$fid]['#weight'] = $file['weight'] + $microweight;
+ $microweight += 0.001;
+ }
+ }
+ uasort($form_state['values']['files'], 'element_sort');
+ }
+}
+
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 5 Jun 2009 21:45:57 -0000
@@ -7,3 +7,9 @@ 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
+files[] = upload.file.inc
+files[] = upload.form.inc
+files[] = upload.pages.inc
Index: modules/upload/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v
retrieving revision 1.241
diff -u -p -r1.241 upload.module
--- modules/upload/upload.module 27 May 2009 18:34:02 -0000 1.241
+++ modules/upload/upload.module 5 Jun 2009 21:45:57 -0000
@@ -23,39 +23,6 @@ function upload_help($path, $arg) {
}
/**
- * Implement 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),
- ),
- );
-}
-
-/**
- * Implement 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
}
/**
- * Implement 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.
@@ -145,70 +92,6 @@ function _upload_file_limits($user) {
);
}
-/**
- * Implement hook_file_download().
- */
-function upload_file_download($filepath) {
- $filepath = file_create_path($filepath);
- $file = db_query("SELECT f.*, u.nid FROM {files} f INNER JOIN {upload} u ON f.fid = u.fid WHERE filepath = :path", array(':path' => $filepath))->fetchObject();
-
- if ($file && user_access('view uploaded files') && ($node = node_load($file->nid)) && node_access('view', $node)) {
- return array(
- 'Content-Type' => $file->filemime,
- 'Content-Length' => $file->filesize,
- );
- }
- else {
- return -1;
- }
-}
-
-/**
- * Save new uploads and store them in the session to be associated to the node
- * on upload_save.
- *
- * @param $node
- * A node object to associate with uploaded files.
- */
-function upload_node_form_submit(&$form, &$form_state) {
- global $user;
-
- $limits = _upload_file_limits($user);
- $validators = array(
- 'file_validate_extensions' => array($limits['extensions']),
- 'file_validate_image_resolution' => array($limits['resolution']),
- 'file_validate_size' => array($limits['file_size'], $limits['user_size']),
- );
-
- // Save new file uploads.
- if (user_access('upload files') && ($file = file_save_upload('upload', $validators, file_directory_path()))) {
- $file->list = variable_get('upload_list_default', 1);
- $file->description = $file->filename;
- $file->weight = 0;
- $file->new = TRUE;
- $form['#node']->files[$file->fid] = $file;
- $form_state['values']['files'][$file->fid] = (array)$file;
- }
-
- if (isset($form_state['values']['files'])) {
- foreach ($form_state['values']['files'] as $fid => $file) {
- $form_state['values']['files'][$fid]['new'] = !empty($form['#node']->files[$fid]->new);
- }
- }
-
- // Order the form according to the set file weight values.
- if (!empty($form_state['values']['files'])) {
- $microweight = 0.001;
- foreach ($form_state['values']['files'] as $fid => $file) {
- if (is_numeric($fid)) {
- $form_state['values']['files'][$fid]['#weight'] = $file['weight'] + $microweight;
- $microweight += 0.001;
- }
- }
- uasort($form_state['values']['files'], 'element_sort');
- }
-}
-
function upload_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
$form['workflow']['upload'] = array(
@@ -277,26 +160,6 @@ function upload_file_load($files) {
}
/**
- * Implement hook_file_references().
- */
-function upload_file_references($file) {
- // If upload.module is still using a file, do not let other modules delete it.
- $file_used = (bool) db_query_range('SELECT 1 FROM {upload} WHERE fid = :fid', array(':fid' => $file->fid), 0, 1)->fetchField();
- if ($file_used) {
- // Return the name of the module and how many references it has to the file.
- return array('upload' => $count);
- }
-}
-
-/**
- * Implement hook_file_delete().
- */
-function upload_file_delete($file) {
- // Delete all information associated with the file.
- db_delete('upload')->condition('fid', $file->fid)->execute();
-}
-
-/**
* Implement hook_node_load().
*/
function upload_node_load($nodes, $types) {
@@ -381,50 +244,6 @@ function upload_node_view($node, $teaser
}
/**
- * Implement hook_node_insert().
- */
-function upload_node_insert($node) {
- if (user_access('upload files')) {
- upload_save($node);
- }
-}
-
-/**
- * Implement hook_node_update().
- */
-function upload_node_update($node) {
- if (user_access('upload files')) {
- upload_save($node);
- }
-}
-
-/**
- * Implement 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);
- }
-}
-
-/**
- * Implement 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);
- }
-}
-
-/**
* Implement hook_node_search_result().
*/
function upload_node_search_result($node) {
@@ -631,69 +450,3 @@ function theme_upload_form_new($form) {
return $output;
}
-/**
- * Menu-callback for JavaScript-based uploads.
- */
-function upload_js() {
- $cached_form_state = array();
- $files = array();
-
- // Load the form from the Form API cache.
- if (!($cached_form = form_get_cache($_POST['form_build_id'], $cached_form_state)) || !isset($cached_form['#node']) || !isset($cached_form['attachments'])) {
- form_set_error('form_token', t('Validation error, please try again. If this error persists, please contact the site administrator.'));
- $output = theme('status_messages');
- print drupal_to_js(array('status' => TRUE, 'data' => $output));
- exit();
- }
-
- $form_state = array('values' => $_POST);
-
- // Handle new uploads, and merge tmp files into node-files.
- upload_node_form_submit($cached_form, $form_state);
-
- if (!empty($form_state['values']['files'])) {
- foreach ($form_state['values']['files'] as $fid => $file) {
- if (isset($cached_form['#node']->files[$fid])) {
- $files[$fid] = $cached_form['#node']->files[$fid];
- }
- }
- }
-
- $node = $cached_form['#node'];
-
- $node->files = $files;
-
- $form = _upload_form($node);
-
- unset($cached_form['attachments']['wrapper']['new']);
- $cached_form['attachments']['wrapper'] = array_merge($cached_form['attachments']['wrapper'], $form);
-
- $cached_form['attachments']['#collapsed'] = FALSE;
-
- form_set_cache($_POST['form_build_id'], $cached_form, $cached_form_state);
-
- foreach ($files as $fid => $file) {
- if (is_numeric($fid)) {
- $form['files'][$fid]['description']['#default_value'] = $form_state['values']['files'][$fid]['description'];
- $form['files'][$fid]['list']['#default_value'] = !empty($form_state['values']['files'][$fid]['list']);
- $form['files'][$fid]['remove']['#default_value'] = !empty($form_state['values']['files'][$fid]['remove']);
- $form['files'][$fid]['weight']['#default_value'] = $form_state['values']['files'][$fid]['weight'];
- }
- }
-
- // Render the form for output.
- $form += array(
- '#tree' => FALSE,
- '#parents' => array(),
- );
- drupal_alter('form', $form, array(), 'upload_js');
- $form_state = array('submitted' => FALSE, 'programmed' => FALSE);
- $form = form_builder('upload_js', $form, $form_state);
- $output = theme('status_messages') . drupal_render($form);
-
- // We send the updated file attachments form.
- // Don't call drupal_json(). ahah.js uses an iframe and
- // the header output by drupal_json() causes problems in some browsers.
- print drupal_to_js(array('status' => TRUE, 'data' => $output));
- exit;
-}
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 5 Jun 2009 21:44:45 -0000
@@ -0,0 +1,52 @@
+condition('nid', $node->nid)->execute();
+ if (!is_array($node->files)) {
+ return;
+ }
+ foreach ($node->files as $file) {
+ file_delete($file);
+ }
+}
+
+/**
+ * Implement 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.pages.inc
===================================================================
RCS file: modules/upload/upload.pages.inc
diff -N modules/upload/upload.pages.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.pages.inc 5 Jun 2009 21:45:57 -0000
@@ -0,0 +1,74 @@
+ TRUE, 'data' => $output));
+ exit();
+ }
+
+ $form_state = array('values' => $_POST);
+
+ // Handle new uploads, and merge tmp files into node-files.
+ upload_node_form_submit($cached_form, $form_state);
+
+ if (!empty($form_state['values']['files'])) {
+ foreach ($form_state['values']['files'] as $fid => $file) {
+ if (isset($cached_form['#node']->files[$fid])) {
+ $files[$fid] = $cached_form['#node']->files[$fid];
+ }
+ }
+ }
+
+ $node = $cached_form['#node'];
+
+ $node->files = $files;
+
+ $form = _upload_form($node);
+
+ unset($cached_form['attachments']['wrapper']['new']);
+ $cached_form['attachments']['wrapper'] = array_merge($cached_form['attachments']['wrapper'], $form);
+
+ $cached_form['attachments']['#collapsed'] = FALSE;
+
+ form_set_cache($_POST['form_build_id'], $cached_form, $cached_form_state);
+
+ foreach ($files as $fid => $file) {
+ if (is_numeric($fid)) {
+ $form['files'][$fid]['description']['#default_value'] = $form_state['values']['files'][$fid]['description'];
+ $form['files'][$fid]['list']['#default_value'] = !empty($form_state['values']['files'][$fid]['list']);
+ $form['files'][$fid]['remove']['#default_value'] = !empty($form_state['values']['files'][$fid]['remove']);
+ $form['files'][$fid]['weight']['#default_value'] = $form_state['values']['files'][$fid]['weight'];
+ }
+ }
+
+ // Render the form for output.
+ $form += array(
+ '#tree' => FALSE,
+ '#parents' => array(),
+ );
+ drupal_alter('form', $form, array(), 'upload_js');
+ $form_state = array('submitted' => FALSE, 'programmed' => FALSE);
+ $form = form_builder('upload_js', $form, $form_state);
+ $output = theme('status_messages') . drupal_render($form);
+
+ // We send the updated file attachments form.
+ // Don't call drupal_json(). ahah.js uses an iframe and
+ // the header output by drupal_json() causes problems in some browsers.
+ print drupal_to_js(array('status' => TRUE, 'data' => $output));
+ exit;
+}
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 5 Jun 2009 21:44:44 -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;
+}
+
+/**
+ * Implement 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 5 Jun 2009 21:44:45 -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 5 Jun 2009 21:44:41 -0000
@@ -0,0 +1,31 @@
+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 5 Jun 2009 21:44:42 -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;
+ }
+}
+
+/**
+ * Implement 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.file.inc
===================================================================
RCS file: modules/user/user.file.inc
diff -N modules/user/user.file.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.file.inc 5 Jun 2009 21:44:44 -0000
@@ -0,0 +1,43 @@
+ $info['mime_type']);
+ }
+}
+
+/**
+ * Implement hook_file_references().
+ */
+function user_file_references($file) {
+ // Determine if the file is used by this module.
+ $file_used = (bool) db_query_range('SELECT 1 FROM {users} WHERE picture = :fid', array(':fid' => $file->fid), 0, 1)->fetchField();
+ if ($file_used) {
+ // Return the name of the module and how many references it has to the file.
+ return array('user' => $count);
+ }
+}
+
+/**
+ * Implement hook_file_delete().
+ */
+function user_file_delete($file) {
+ // Remove any references to the file.
+ db_update('users')
+ ->fields(array('picture' => 0))
+ ->condition('picture', $file->fid)
+ ->execute();
+}
+
Index: modules/user/user.form.inc
===================================================================
RCS file: modules/user/user.form.inc
diff -N modules/user/user.form.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.form.inc 5 Jun 2009 21:45:59 -0000
@@ -0,0 +1,277 @@
+uid) {
+ drupal_goto('user/' . $user->uid);
+ }
+
+ // Display login form:
+ $form['name'] = array('#type' => 'textfield',
+ '#title' => t('Username'),
+ '#size' => 60,
+ '#maxlength' => USERNAME_MAX_LENGTH,
+ '#required' => TRUE,
+ );
+
+ $form['name']['#description'] = t('Enter your @s username.', array('@s' => variable_get('site_name', 'Drupal')));
+ $form['pass'] = array('#type' => 'password',
+ '#title' => t('Password'),
+ '#description' => t('Enter the password that accompanies your username.'),
+ '#required' => TRUE,
+ );
+ $form['#validate'] = user_login_default_validators();
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Log in'), '#weight' => 2);
+
+ return $form;
+}
+
+/**
+ * A FAPI validate handler. Sets an error if supplied username has been blocked.
+ */
+function user_login_name_validate($form, &$form_state) {
+ if (isset($form_state['values']['name']) && user_is_blocked($form_state['values']['name'])) {
+ // Blocked in user administration.
+ form_set_error('name', t('The username %name has not been activated or is blocked.', array('%name' => $form_state['values']['name'])));
+ }
+}
+
+/**
+ * A validate handler on the login form. Check supplied username/password
+ * against local users table. If successful, sets the global $user object.
+ */
+function user_login_authenticate_validate($form, &$form_state) {
+ user_authenticate($form_state['values']);
+}
+
+/**
+ * A validate handler on the login form. Should be the last validator. Sets an
+ * error if user has not been authenticated yet.
+ */
+function user_login_final_validate($form, &$form_state) {
+ global $user;
+ if (!$user->uid) {
+ form_set_error('name', t('Sorry, unrecognized username or password. Have you forgotten your password?', array('@password' => url('user/password'))));
+ watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_state['values']['name']));
+ }
+}
+
+/**
+ * Submit handler for the login form. Redirects the user to a page.
+ *
+ * The user is redirected to the My Account page. Setting the destination in
+ * the query string (as done by the user login block) overrides the redirect.
+ */
+function user_login_submit($form, &$form_state) {
+ global $user;
+ if ($user->uid) {
+ $form_state['redirect'] = 'user/' . $user->uid;
+ return;
+ }
+}
+
+function user_login_block() {
+ $form = array(
+ '#action' => url($_GET['q'], array('query' => drupal_get_destination())),
+ '#id' => 'user-login-form',
+ '#validate' => user_login_default_validators(),
+ '#submit' => array('user_login_submit'),
+ );
+ $form['name'] = array('#type' => 'textfield',
+ '#title' => t('Username'),
+ '#maxlength' => USERNAME_MAX_LENGTH,
+ '#size' => 15,
+ '#required' => TRUE,
+ );
+ $form['pass'] = array('#type' => 'password',
+ '#title' => t('Password'),
+ '#maxlength' => 60,
+ '#size' => 15,
+ '#required' => TRUE,
+ );
+ $form['submit'] = array('#type' => 'submit',
+ '#value' => t('Log in'),
+ );
+ $items = array();
+ if (variable_get('user_register', 1)) {
+ $items[] = l(t('Create new account'), 'user/register', array('attributes' => array('title' => t('Create a new user account.'))));
+ }
+ $items[] = l(t('Request new password'), 'user/password', array('attributes' => array('title' => t('Request new password via e-mail.'))));
+ $form['links'] = array('#markup' => theme('item_list', $items));
+ return $form;
+}
+
+/**
+ * Form builder; The user registration form.
+ *
+ * @ingroup forms
+ * @see user_register_validate()
+ * @see user_register_submit()
+ */
+function user_register() {
+ global $user;
+
+ $admin = user_access('administer users');
+
+ // If we aren't admin but already logged on, go to the user page instead.
+ if (!$admin && $user->uid) {
+ drupal_goto('user/' . $user->uid);
+ }
+
+ // Start with the default user edit fields.
+ $form = user_edit_form($form_state, NULL, NULL, TRUE);
+ if ($admin) {
+ $form['account']['notify'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Notify user of new account')
+ );
+ // Redirect back to page which initiated the create request;
+ // usually admin/user/user/create.
+ $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']);
+ }
+
+ // Create a dummy variable for pass-by-reference parameters.
+ $null = NULL;
+ $extra = _user_forms($null, NULL, NULL, 'register');
+
+ // Remove form_group around default fields if there are no other groups.
+ if (!$extra) {
+ foreach (array('name', 'mail', 'pass', 'status', 'roles', 'notify') as $key) {
+ if (isset($form['account'][$key])) {
+ $form[$key] = $form['account'][$key];
+ }
+ }
+ unset($form['account']);
+ }
+ else {
+ $form = array_merge($form, $extra);
+ }
+
+ $form['submit'] = array('#type' => 'submit', '#value' => t('Create new account'), '#weight' => 30);
+ $form['#validate'][] = 'user_register_validate';
+
+ return $form;
+}
+
+function user_register_validate($form, &$form_state) {
+ user_module_invoke('validate', $form_state['values'], $form_state['values'], 'account');
+}
+
+/**
+ * Submit handler for the user registration form.
+ *
+ * This function is shared by the installation form and the normal registration form,
+ * which is why it can't be in the user.pages.inc file.
+ */
+function user_register_submit($form, &$form_state) {
+ global $base_url;
+ $admin = user_access('administer users');
+
+ $mail = $form_state['values']['mail'];
+ $name = $form_state['values']['name'];
+ if (!variable_get('user_email_verification', TRUE) || $admin) {
+ $pass = $form_state['values']['pass'];
+ }
+ else {
+ $pass = user_password();
+ };
+ $notify = isset($form_state['values']['notify']) ? $form_state['values']['notify'] : NULL;
+ $from = variable_get('site_mail', ini_get('sendmail_from'));
+ if (isset($form_state['values']['roles'])) {
+ // Remove unset roles.
+ $roles = array_filter($form_state['values']['roles']);
+ }
+ else {
+ $roles = array();
+ }
+
+ if (!$admin && array_intersect(array_keys($form_state['values']), array('uid', 'roles', 'init', 'session', 'status'))) {
+ watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
+ $form_state['redirect'] = 'user/register';
+ return;
+ }
+ // The unset below is needed to prevent these form values from being saved as
+ // user data.
+ unset($form_state['values']['form_token'], $form_state['values']['submit'], $form_state['values']['op'], $form_state['values']['notify'], $form_state['values']['form_id'], $form_state['values']['affiliates'], $form_state['values']['destination'], $form_state['values']['form_build_id']);
+
+ $merge_data = array('pass' => $pass, 'init' => $mail, 'roles' => $roles);
+ if (!$admin) {
+ // Set the user's status because it was not displayed in the form.
+ $merge_data['status'] = variable_get('user_register', 1) == 1;
+ }
+ $account = user_save('', array_merge($form_state['values'], $merge_data));
+ // Terminate if an error occurred during user_save().
+ if (!$account) {
+ drupal_set_message(t("Error saving user account."), 'error');
+ $form_state['redirect'] = '';
+ return;
+ }
+ $form_state['user'] = $account;
+
+ watchdog('user', 'New user: %name (%email).', array('%name' => $name, '%email' => $mail), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));
+
+ // The first user may login immediately, and receives a customized welcome e-mail.
+ if ($account->uid == 1) {
+ drupal_set_message(t('Welcome to Drupal. You are now logged in as user #1, which gives you full control over your website.'));
+ if (variable_get('user_email_verification', TRUE)) {
+ drupal_set_message(t('
Your password is %pass. You may change your password below.
', array('%pass' => $pass)));
+ }
+
+ user_authenticate(array_merge($form_state['values'], $merge_data));
+
+ $form_state['redirect'] = 'user/1/edit';
+ return;
+ }
+ else {
+ // Add plain text password into user account to generate mail tokens.
+ $account->password = $pass;
+ if ($admin && !$notify) {
+ drupal_set_message(t('Created a new user account for %name. No e-mail has been sent.', array('@url' => url("user/$account->uid"), '%name' => $account->name)));
+ }
+ elseif (!variable_get('user_email_verification', TRUE) && $account->status && !$admin) {
+ // No e-mail verification is required, create new user account, and login
+ // user immediately.
+ _user_mail_notify('register_no_approval_required', $account);
+ if (user_authenticate(array_merge($form_state['values'], $merge_data))) {
+ drupal_set_message(t('Registration successful. You are now logged in.'));
+ }
+ $form_state['redirect'] = '';
+ return;
+ }
+ elseif ($account->status || $notify) {
+ // Create new user account, no administrator approval required.
+ $op = $notify ? 'register_admin_created' : 'register_no_approval_required';
+ _user_mail_notify($op, $account);
+ if ($notify) {
+ drupal_set_message(t('Password and further instructions have been e-mailed to the new user %name.', array('@url' => url("user/$account->uid"), '%name' => $account->name)));
+ }
+ else {
+ drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
+ $form_state['redirect'] = '';
+ return;
+ }
+ }
+ else {
+ // Create new user account, administrator approval required.
+ _user_mail_notify('register_pending_approval', $account);
+ drupal_set_message(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator. In the meantime, a welcome message with further instructions has been sent to your e-mail address.'));
+ $form_state['redirect'] = '';
+ return;
+
+ }
+ }
+}
+
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 5 Jun 2009 21:45:59 -0000
@@ -9,3 +9,11 @@ files[] = user.admin.inc
files[] = user.pages.inc
files[] = user.install
required = TRUE
+files[] = user.registry.inc
+files[] = user.actions.inc
+files[] = user.mail.inc
+files[] = user.user.inc
+files[] = user.block.inc
+files[] = user.search.inc
+files[] = user.file.inc
+files[] = user.form.inc
Index: modules/user/user.mail.inc
===================================================================
RCS file: modules/user/user.mail.inc
diff -N modules/user/user.mail.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.mail.inc 5 Jun 2009 21:44:41 -0000
@@ -0,0 +1,18 @@
+ array(
- 'arguments' => array('account' => NULL),
- 'template' => 'user-picture',
- ),
- 'user_profile' => array(
- 'arguments' => array('elements' => NULL),
- 'template' => 'user-profile',
- 'file' => 'user.pages.inc',
- ),
- 'user_profile_category' => array(
- 'arguments' => array('element' => NULL),
- 'template' => 'user-profile-category',
- 'file' => 'user.pages.inc',
- ),
- 'user_profile_item' => array(
- 'arguments' => array('element' => NULL),
- 'template' => 'user-profile-item',
- 'file' => 'user.pages.inc',
- ),
- 'user_list' => array(
- 'arguments' => array('users' => NULL, 'title' => NULL),
- ),
- 'user_admin_perm' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
- 'user_admin_new_role' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
- 'user_admin_account' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
- 'user_filter_form' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
- 'user_filters' => array(
- 'arguments' => array('form' => NULL),
- 'file' => 'user.admin.inc',
- ),
- 'user_signature' => array(
- 'arguments' => array('signature' => NULL),
- ),
- );
-}
-
-/**
- * Implement hook_fieldable_info().
- */
-function user_fieldable_info() {
- $return = array(
- 'user' => array(
- 'name' => t('User'),
- 'id key' => 'uid',
- ),
- );
- return $return;
-}
-
-/**
- * Implement hook_field_build_modes().
- */
-function user_field_build_modes($obj_type) {
- $modes = array();
- if ($obj_type == 'user') {
- $modes = array(
- 'full' => t('User account'),
- );
- }
- return $modes;
-}
-
function user_external_load($authname) {
$uid = db_query("SELECT uid FROM {authmap} WHERE authname = :authname", array(':authname' => $authname))->fetchField();
@@ -784,123 +705,6 @@ function user_is_blocked($name) {
}
/**
- * Implement 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.'))),
- ),
- );
-}
-
-/**
- * Implement hook_file_download().
- *
- * Ensure that user pictures (avatars) are always downloadable.
- */
-function user_file_download($filepath) {
- if (strpos($filepath, variable_get('user_picture_path', 'pictures') . '/picture-') === 0) {
- $info = image_get_info(file_create_path($filepath));
- return array('Content-Type' => $info['mime_type']);
- }
-}
-
-/**
- * Implement hook_file_references().
- */
-function user_file_references($file) {
- // Determine if the file is used by this module.
- $file_used = (bool) db_query_range('SELECT 1 FROM {users} WHERE picture = :fid', array(':fid' => $file->fid), 0, 1)->fetchField();
- if ($file_used) {
- // Return the name of the module and how many references it has to the file.
- return array('user' => $count);
- }
-}
-
-/**
- * Implement hook_file_delete().
- */
-function user_file_delete($file) {
- // Remove any references to the file.
- db_update('users')
- ->fields(array('picture' => 0))
- ->condition('picture', $file->fid)
- ->execute();
-}
-
-/**
- * Implement 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;
- }
- }
-}
-
-/**
- * Implement hook_elements().
- */
-function user_elements() {
- return array(
- 'user_profile_category' => array(
- '#theme_wrapper' => 'user_profile_category'
- ),
- 'user_profile_item' => array(
- '#theme' => 'user_profile_item'
- ),
- );
-}
-
-/**
* Implement hook_user_view().
*/
function user_user_view(&$edit, &$account, $category = NULL) {
@@ -925,182 +729,6 @@ function user_user_view(&$edit, &$accoun
}
/**
- * Implement 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);
- }
-}
-
-/**
- * Implement 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'])));
- }
- }
- }
-}
-
-/**
- * Implement 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']);
- }
- }
-}
-
-/**
- * Implement hook_user_categories().
- */
-function user_user_categories() {
- 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())),
- '#id' => 'user-login-form',
- '#validate' => user_login_default_validators(),
- '#submit' => array('user_login_submit'),
- );
- $form['name'] = array('#type' => 'textfield',
- '#title' => t('Username'),
- '#maxlength' => USERNAME_MAX_LENGTH,
- '#size' => 15,
- '#required' => TRUE,
- );
- $form['pass'] = array('#type' => 'password',
- '#title' => t('Password'),
- '#maxlength' => 60,
- '#size' => 15,
- '#required' => TRUE,
- );
- $form['submit'] = array('#type' => 'submit',
- '#value' => t('Log in'),
- );
- $items = array();
- if (variable_get('user_register', 1)) {
- $items[] = l(t('Create new account'), 'user/register', array('attributes' => array('title' => t('Create a new user account.'))));
- }
- $items[] = l(t('Request new password'), 'user/password', array('attributes' => array('title' => t('Request new password via e-mail.'))));
- $form['links'] = array('#markup' => theme('item_list', $items));
- return $form;
-}
-
-/**
- * Implement 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;
-}
-
-/**
- * Implement 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.
');
- return $form;
- }
-}
-
-/**
- * Implement 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;
- }
-}
-
-/**
* Implement hook_block_view().
*/
function user_block_view($delta = '') {
@@ -1276,193 +904,6 @@ function user_load_self($arg) {
return $arg;
}
-/**
- * Implement hook_menu().
- */
-function user_menu() {
- $items['user/autocomplete'] = array(
- 'title' => 'User autocomplete',
- 'page callback' => 'user_autocomplete',
- 'access callback' => 'user_access',
- 'access arguments' => array('access user profiles'),
- 'type' => MENU_CALLBACK,
- );
-
- // Registration and login pages.
- $items['user'] = array(
- 'title' => 'User account',
- 'page callback' => 'user_page',
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
-
- $items['user/login'] = array(
- 'title' => 'Log in',
- 'access callback' => 'user_is_anonymous',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
-
- $items['user/register'] = array(
- 'title' => 'Create new account',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_register'),
- 'access callback' => 'user_register_access',
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items['user/password'] = array(
- 'title' => 'Request new password',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_pass'),
- 'access callback' => 'user_is_anonymous',
- 'type' => MENU_LOCAL_TASK,
- );
- $items['user/reset/%/%/%'] = array(
- 'title' => 'Reset password',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_pass_reset', 2, 3, 4),
- 'access callback' => TRUE,
- 'type' => MENU_CALLBACK,
- );
-
- $items['user/logout'] = array(
- 'title' => 'Log out',
- 'access callback' => 'user_is_logged_in',
- 'page callback' => 'user_logout',
- 'weight' => 10,
- 'menu_name' => 'user-menu',
- );
-
- // User administration pages.
- $items['admin/user'] = array(
- 'title' => 'User management',
- 'description' => "Manage your site's users, groups and access to site features.",
- 'position' => 'left',
- 'page callback' => 'system_admin_menu_block_page',
- 'access callback' => 'system_admin_menu_block_access',
- 'access arguments' => array('admin/user', 'access administration pages'),
- );
- $items['admin/user/user'] = array(
- 'title' => 'Users',
- 'description' => 'List, add, and edit users.',
- 'page callback' => 'user_admin',
- 'page arguments' => array('list'),
- 'access arguments' => array('administer users'),
- );
- $items['admin/user/user/list'] = array(
- 'title' => 'List',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
- $items['admin/user/user/create'] = array(
- 'title' => 'Add user',
- 'page arguments' => array('create'),
- 'access arguments' => array('administer users'),
- 'type' => MENU_LOCAL_TASK,
- );
- $items['admin/user/settings'] = array(
- 'title' => 'User settings',
- 'description' => 'Configure default behavior of users, including registration requirements, e-mails, and user pictures.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_admin_settings'),
- 'access arguments' => array('administer users'),
- );
-
- // Permission administration pages.
- $items['admin/user/permissions'] = array(
- 'title' => 'Permissions',
- 'description' => 'Determine access to features by selecting permissions for roles.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_admin_perm'),
- 'access arguments' => array('administer permissions'),
- );
- $items['admin/user/roles'] = array(
- 'title' => 'Roles',
- 'description' => 'List, edit, or add user roles.',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_admin_new_role'),
- 'access arguments' => array('administer permissions'),
- );
- $items['admin/user/roles/edit'] = array(
- 'title' => 'Edit role',
- 'page arguments' => array('user_admin_role'),
- 'access arguments' => array('administer permissions'),
- 'type' => MENU_CALLBACK,
- );
-
- $items['user/%user_uid_optional'] = array(
- 'title' => 'My account',
- 'title callback' => 'user_page_title',
- 'title arguments' => array(1),
- 'page callback' => 'user_view',
- 'page arguments' => array(1),
- 'access callback' => 'user_view_access',
- 'access arguments' => array(1),
- 'weight' => -10,
- 'menu_name' => 'user-menu',
- );
-
- $items['user/%user/view'] = array(
- 'title' => 'View',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'weight' => -10,
- );
-
- $items['user/%user/cancel'] = array(
- 'title' => 'Cancel account',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('user_cancel_confirm_form', 1),
- 'access callback' => 'user_cancel_access',
- 'access arguments' => array(1),
- 'type' => MENU_CALLBACK,
- );
-
- $items['user/%user/cancel/confirm/%/%'] = array(
- 'title' => 'Confirm account cancellation',
- 'page callback' => 'user_cancel_confirm',
- 'page arguments' => array(1, 4, 5),
- 'access callback' => 'user_cancel_access',
- 'access arguments' => array(1),
- 'type' => MENU_CALLBACK,
- );
-
- $items['user/%user/edit'] = array(
- 'title' => 'Edit',
- 'page callback' => 'user_edit',
- 'page arguments' => array(1),
- 'access callback' => 'user_edit_access',
- 'access arguments' => array(1),
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items['user/%user_category/edit/account'] = array(
- 'title' => 'Account',
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'load arguments' => array('%map', '%index'),
- );
-
- if (($categories = _user_categories()) && (count($categories) > 1)) {
- foreach ($categories as $key => $category) {
- // 'account' is already handled by the MENU_DEFAULT_LOCAL_TASK.
- if ($category['name'] != 'account') {
- $items['user/%user_category/edit/' . $category['name']] = array(
- 'title callback' => 'check_plain',
- 'title arguments' => array($category['title']),
- 'page callback' => 'user_edit',
- 'page arguments' => array(1, 3),
- 'access callback' => isset($category['access callback']) ? $category['access callback'] : 'user_edit_access',
- 'access arguments' => isset($category['access arguments']) ? $category['access arguments'] : array(1),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => $category['weight'],
- 'load arguments' => array('%map', '%index'),
- 'tab_parent' => 'user/%/edit',
- );
- }
- }
- }
- return $items;
-}
-
function user_init() {
drupal_add_css(drupal_get_path('module', 'user') . '/user.css');
}
@@ -1576,39 +1017,6 @@ function user_set_authmaps($account, $au
}
/**
- * Form builder; the main user login form.
- *
- * @ingroup forms
- */
-function user_login(&$form_state) {
- global $user;
-
- // If we are already logged on, go to the user page instead.
- if ($user->uid) {
- drupal_goto('user/' . $user->uid);
- }
-
- // Display login form:
- $form['name'] = array('#type' => 'textfield',
- '#title' => t('Username'),
- '#size' => 60,
- '#maxlength' => USERNAME_MAX_LENGTH,
- '#required' => TRUE,
- );
-
- $form['name']['#description'] = t('Enter your @s username.', array('@s' => variable_get('site_name', 'Drupal')));
- $form['pass'] = array('#type' => 'password',
- '#title' => t('Password'),
- '#description' => t('Enter the password that accompanies your username.'),
- '#required' => TRUE,
- );
- $form['#validate'] = user_login_default_validators();
- $form['submit'] = array('#type' => 'submit', '#value' => t('Log in'), '#weight' => 2);
-
- return $form;
-}
-
-/**
* Set up a series for validators which check for blocked users,
* then authenticate against local database, then return an error if
* authentication fails. Distributed authentication modules are welcome
@@ -1630,36 +1038,6 @@ function user_login_default_validators()
}
/**
- * A FAPI validate handler. Sets an error if supplied username has been blocked.
- */
-function user_login_name_validate($form, &$form_state) {
- if (isset($form_state['values']['name']) && user_is_blocked($form_state['values']['name'])) {
- // Blocked in user administration.
- form_set_error('name', t('The username %name has not been activated or is blocked.', array('%name' => $form_state['values']['name'])));
- }
-}
-
-/**
- * A validate handler on the login form. Check supplied username/password
- * against local users table. If successful, sets the global $user object.
- */
-function user_login_authenticate_validate($form, &$form_state) {
- user_authenticate($form_state['values']);
-}
-
-/**
- * A validate handler on the login form. Should be the last validator. Sets an
- * error if user has not been authenticated yet.
- */
-function user_login_final_validate($form, &$form_state) {
- global $user;
- if (!$user->uid) {
- form_set_error('name', t('Sorry, unrecognized username or password. Have you forgotten your password?', array('@password' => url('user/password'))));
- watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_state['values']['name']));
- }
-}
-
-/**
* Try to log in the user locally.
*
* @param $form_values
@@ -1727,20 +1105,6 @@ function user_authenticate_finalize(&$ed
}
/**
- * Submit handler for the login form. Redirects the user to a page.
- *
- * The user is redirected to the My Account page. Setting the destination in
- * the query string (as done by the user login block) overrides the redirect.
- */
-function user_login_submit($form, &$form_state) {
- global $user;
- if ($user->uid) {
- $form_state['redirect'] = 'user/' . $user->uid;
- return;
- }
-}
-
-/**
* Helper function for authentication modules. Either login in or registers
* the current user, based on username. Either way, the global $user object is
* populated based on $name.
@@ -2059,16 +1423,6 @@ function user_build_content(&$account) {
}
/**
- * Implement hook_mail().
- */
-function user_mail($key, &$message, $params) {
- $language = $message['language'];
- $variables = user_mail_tokens($params['account'], $language);
- $message['subject'] .= _user_mail_text($key . '_subject', $language, $variables);
- $message['body'][] = _user_mail_text($key . '_body', $language, $variables);
-}
-
-/**
* Returns a mail string for a variable name.
*
* Used by user_mail() and the settings forms to retrieve strings.
@@ -2186,205 +1540,6 @@ function user_roles($membersonly = FALSE
}
/**
- * Implement hook_user_operations().
- */
-function user_user_operations($form_state = array()) {
- $operations = array(
- 'unblock' => array(
- 'label' => t('Unblock the selected users'),
- 'callback' => 'user_user_operations_unblock',
- ),
- 'block' => array(
- 'label' => t('Block the selected users'),
- 'callback' => 'user_user_operations_block',
- ),
- 'cancel' => array(
- 'label' => t('Cancel the selected user accounts'),
- ),
- );
-
- if (user_access('administer permissions')) {
- $roles = user_roles(TRUE);
- unset($roles[DRUPAL_AUTHENTICATED_RID]); // Can't edit authenticated role.
-
- $add_roles = array();
- foreach ($roles as $key => $value) {
- $add_roles['add_role-' . $key] = $value;
- }
-
- $remove_roles = array();
- foreach ($roles as $key => $value) {
- $remove_roles['remove_role-' . $key] = $value;
- }
-
- if (count($roles)) {
- $role_operations = array(
- t('Add a role to the selected users') => array(
- 'label' => $add_roles,
- ),
- t('Remove a role from the selected users') => array(
- 'label' => $remove_roles,
- ),
- );
-
- $operations += $role_operations;
- }
- }
-
- // If the form has been posted, we need to insert the proper data for
- // role editing if necessary.
- if (!empty($form_state['submitted'])) {
- $operation_rid = explode('-', $form_state['values']['operation']);
- $operation = $operation_rid[0];
- if ($operation == 'add_role' || $operation == 'remove_role') {
- $rid = $operation_rid[1];
- if (user_access('administer permissions')) {
- $operations[$form_state['values']['operation']] = array(
- 'callback' => 'user_multiple_role_edit',
- 'callback arguments' => array($operation, $rid),
- );
- }
- else {
- watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
- return;
- }
- }
- }
-
- return $operations;
-}
-
-/**
- * Callback function for admin mass unblocking users.
- */
-function user_user_operations_unblock($accounts) {
- foreach ($accounts as $uid) {
- $account = user_load($uid);
- // Skip unblocking user if they are already unblocked.
- if ($account !== FALSE && $account->status == 0) {
- user_save($account, array('status' => 1));
- }
- }
-}
-
-/**
- * Callback function for admin mass blocking users.
- */
-function user_user_operations_block($accounts) {
- foreach ($accounts as $uid) {
- $account = user_load($uid);
- // Skip blocking user if they are already blocked.
- if ($account !== FALSE && $account->status == 1) {
- user_save($account, array('status' => 0));
- }
- }
-}
-
-/**
- * Callback function for admin mass adding/deleting a user role.
- */
-function user_multiple_role_edit($accounts, $operation, $rid) {
- // The role name is not necessary as user_save() will reload the user
- // object, but some modules' hook_user() may look at this first.
- $role_name = db_query('SELECT name FROM {role} WHERE rid = :rid', array(':rid' => $rid))->fetchField();
-
- switch ($operation) {
- case 'add_role':
- foreach ($accounts as $uid) {
- $account = user_load($uid);
- // Skip adding the role to the user if they already have it.
- if ($account !== FALSE && !isset($account->roles[$rid])) {
- $roles = $account->roles + array($rid => $role_name);
- user_save($account, array('roles' => $roles));
- }
- }
- break;
- case 'remove_role':
- foreach ($accounts as $uid) {
- $account = user_load($uid);
- // Skip removing the role from the user if they already don't have it.
- if ($account !== FALSE && isset($account->roles[$rid])) {
- $roles = array_diff($account->roles, array($rid => $role_name));
- user_save($account, array('roles' => $roles));
- }
- }
- break;
- }
-}
-
-function user_multiple_cancel_confirm(&$form_state) {
- $edit = $form_state['input'];
-
- $form['accounts'] = array('#prefix' => '
', '#suffix' => '
', '#tree' => TRUE);
- // array_filter() returns only elements with TRUE values.
- foreach (array_filter($edit['accounts']) as $uid => $value) {
- $user = db_query('SELECT name FROM {users} WHERE uid = :uid', array(':uid' => $uid))->fetchField();
- $form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '
', '#suffix' => check_plain($user) . "
\n");
- }
-
- $form['operation'] = array('#type' => 'hidden', '#value' => 'cancel');
-
- module_load_include('inc', 'user', 'user.pages');
- $form['user_cancel_method'] = array(
- '#type' => 'item',
- '#title' => t('When cancelling these accounts'),
- );
- $form['user_cancel_method'] += user_cancel_methods();
- // Remove method descriptions.
- foreach (element_children($form['user_cancel_method']) as $element) {
- unset($form['user_cancel_method'][$element]['#description']);
- }
-
- // Allow to send the account cancellation confirmation mail.
- $form['user_cancel_confirm'] = array(
- '#type' => 'checkbox',
- '#title' => t('Require e-mail confirmation to cancel account.'),
- '#default_value' => FALSE,
- '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'),
- );
- // Also allow to send account canceled notification mail, if enabled.
- $form['user_cancel_notify'] = array(
- '#type' => 'checkbox',
- '#title' => t('Notify user when account is canceled.'),
- '#default_value' => FALSE,
- '#access' => variable_get('user_mail_status_canceled_notify', FALSE),
- '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'),
- );
-
- return confirm_form($form,
- t('Are you sure you want to cancel these user accounts?'),
- 'admin/user/user', t('This action cannot be undone.'),
- t('Cancel accounts'), t('Cancel'));
-}
-
-/**
- * Submit handler for mass-account cancellation form.
- *
- * @see user_multiple_cancel_confirm()
- * @see user_cancel_confirm_form_submit()
- */
-function user_multiple_cancel_confirm_submit($form, &$form_state) {
- global $user;
-
- if ($form_state['values']['confirm']) {
- foreach ($form_state['values']['accounts'] as $uid => $value) {
- // Prevent user administrators from deleting themselves without confirmation.
- if ($uid == $user->uid) {
- $admin_form_state = $form_state;
- unset($admin_form_state['values']['user_cancel_confirm']);
- $admin_form_state['values']['_account'] = $user;
- user_cancel_confirm_form_submit(array(), $admin_form_state);
- }
- else {
- user_cancel($form_state['values'], $uid, $form_state['values']['user_cancel_method']);
- }
- }
- }
- $form_state['redirect'] = 'admin/user/user';
- return;
-}
-
-/**
* Implement hook_help().
*/
function user_help($path, $arg) {
@@ -2691,234 +1846,6 @@ function user_node_load($nodes, $types)
}
/**
- * Implement hook_hook_info().
- */
-function user_hook_info() {
- return array(
- 'user' => array(
- 'user' => array(
- 'insert' => array(
- 'runs when' => t('After a user account has been created'),
- ),
- 'update' => array(
- 'runs when' => t("After a user's profile has been updated"),
- ),
- 'delete' => array(
- 'runs when' => t('After a user has been deleted')
- ),
- 'login' => array(
- 'runs when' => t('After a user has logged in')
- ),
- 'logout' => array(
- 'runs when' => t('After a user has logged out')
- ),
- 'view' => array(
- 'runs when' => t("When a user's profile is being viewed")
- ),
- ),
- ),
- );
-}
-
-/**
- * Implement hook_action_info().
- */
-function user_action_info() {
- return array(
- 'user_block_user_action' => array(
- 'description' => t('Block current user'),
- 'type' => 'user',
- 'configurable' => FALSE,
- 'hooks' => array(),
- ),
- );
-}
-
-/**
- * Implement 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));
-}
-
-/**
- * Submit handler for the user registration form.
- *
- * This function is shared by the installation form and the normal registration form,
- * which is why it can't be in the user.pages.inc file.
- */
-function user_register_submit($form, &$form_state) {
- global $base_url;
- $admin = user_access('administer users');
-
- $mail = $form_state['values']['mail'];
- $name = $form_state['values']['name'];
- if (!variable_get('user_email_verification', TRUE) || $admin) {
- $pass = $form_state['values']['pass'];
- }
- else {
- $pass = user_password();
- };
- $notify = isset($form_state['values']['notify']) ? $form_state['values']['notify'] : NULL;
- $from = variable_get('site_mail', ini_get('sendmail_from'));
- if (isset($form_state['values']['roles'])) {
- // Remove unset roles.
- $roles = array_filter($form_state['values']['roles']);
- }
- else {
- $roles = array();
- }
-
- if (!$admin && array_intersect(array_keys($form_state['values']), array('uid', 'roles', 'init', 'session', 'status'))) {
- watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
- $form_state['redirect'] = 'user/register';
- return;
- }
- // The unset below is needed to prevent these form values from being saved as
- // user data.
- unset($form_state['values']['form_token'], $form_state['values']['submit'], $form_state['values']['op'], $form_state['values']['notify'], $form_state['values']['form_id'], $form_state['values']['affiliates'], $form_state['values']['destination'], $form_state['values']['form_build_id']);
-
- $merge_data = array('pass' => $pass, 'init' => $mail, 'roles' => $roles);
- if (!$admin) {
- // Set the user's status because it was not displayed in the form.
- $merge_data['status'] = variable_get('user_register', 1) == 1;
- }
- $account = user_save('', array_merge($form_state['values'], $merge_data));
- // Terminate if an error occurred during user_save().
- if (!$account) {
- drupal_set_message(t("Error saving user account."), 'error');
- $form_state['redirect'] = '';
- return;
- }
- $form_state['user'] = $account;
-
- watchdog('user', 'New user: %name (%email).', array('%name' => $name, '%email' => $mail), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));
-
- // The first user may login immediately, and receives a customized welcome e-mail.
- if ($account->uid == 1) {
- drupal_set_message(t('Welcome to Drupal. You are now logged in as user #1, which gives you full control over your website.'));
- if (variable_get('user_email_verification', TRUE)) {
- drupal_set_message(t('
Your password is %pass. You may change your password below.
', array('%pass' => $pass)));
- }
-
- user_authenticate(array_merge($form_state['values'], $merge_data));
-
- $form_state['redirect'] = 'user/1/edit';
- return;
- }
- else {
- // Add plain text password into user account to generate mail tokens.
- $account->password = $pass;
- if ($admin && !$notify) {
- drupal_set_message(t('Created a new user account for %name. No e-mail has been sent.', array('@url' => url("user/$account->uid"), '%name' => $account->name)));
- }
- elseif (!variable_get('user_email_verification', TRUE) && $account->status && !$admin) {
- // No e-mail verification is required, create new user account, and login
- // user immediately.
- _user_mail_notify('register_no_approval_required', $account);
- if (user_authenticate(array_merge($form_state['values'], $merge_data))) {
- drupal_set_message(t('Registration successful. You are now logged in.'));
- }
- $form_state['redirect'] = '';
- return;
- }
- elseif ($account->status || $notify) {
- // Create new user account, no administrator approval required.
- $op = $notify ? 'register_admin_created' : 'register_no_approval_required';
- _user_mail_notify($op, $account);
- if ($notify) {
- drupal_set_message(t('Password and further instructions have been e-mailed to the new user %name.', array('@url' => url("user/$account->uid"), '%name' => $account->name)));
- }
- else {
- drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
- $form_state['redirect'] = '';
- return;
- }
- }
- else {
- // Create new user account, administrator approval required.
- _user_mail_notify('register_pending_approval', $account);
- drupal_set_message(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator. In the meantime, a welcome message with further instructions has been sent to your e-mail address.'));
- $form_state['redirect'] = '';
- return;
-
- }
- }
-}
-
-/**
- * Form builder; The user registration form.
- *
- * @ingroup forms
- * @see user_register_validate()
- * @see user_register_submit()
- */
-function user_register() {
- global $user;
-
- $admin = user_access('administer users');
-
- // If we aren't admin but already logged on, go to the user page instead.
- if (!$admin && $user->uid) {
- drupal_goto('user/' . $user->uid);
- }
-
- // Start with the default user edit fields.
- $form = user_edit_form($form_state, NULL, NULL, TRUE);
- if ($admin) {
- $form['account']['notify'] = array(
- '#type' => 'checkbox',
- '#title' => t('Notify user of new account')
- );
- // Redirect back to page which initiated the create request;
- // usually admin/user/user/create.
- $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']);
- }
-
- // Create a dummy variable for pass-by-reference parameters.
- $null = NULL;
- $extra = _user_forms($null, NULL, NULL, 'register');
-
- // Remove form_group around default fields if there are no other groups.
- if (!$extra) {
- foreach (array('name', 'mail', 'pass', 'status', 'roles', 'notify') as $key) {
- if (isset($form['account'][$key])) {
- $form[$key] = $form['account'][$key];
- }
- }
- unset($form['account']);
- }
- else {
- $form = array_merge($form, $extra);
- }
-
- $form['submit'] = array('#type' => 'submit', '#value' => t('Create new account'), '#weight' => 30);
- $form['#validate'][] = 'user_register_validate';
-
- return $form;
-}
-
-function user_register_validate($form, &$form_state) {
- user_module_invoke('validate', $form_state['values'], $form_state['values'], 'account');
-}
-
-/**
* Retrieve a list of all form elements for the specified category.
*/
function _user_forms(&$edit, $account, $category, $hook = 'form') {
Index: modules/user/user.registry.inc
===================================================================
RCS file: modules/user/user.registry.inc
diff -N modules/user/user.registry.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.registry.inc 5 Jun 2009 21:44:41 -0000
@@ -0,0 +1,332 @@
+ 'User autocomplete',
+ 'page callback' => 'user_autocomplete',
+ 'access callback' => 'user_access',
+ 'access arguments' => array('access user profiles'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ // Registration and login pages.
+ $items['user'] = array(
+ 'title' => 'User account',
+ 'page callback' => 'user_page',
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['user/login'] = array(
+ 'title' => 'Log in',
+ 'access callback' => 'user_is_anonymous',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ );
+
+ $items['user/register'] = array(
+ 'title' => 'Create new account',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_register'),
+ 'access callback' => 'user_register_access',
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ $items['user/password'] = array(
+ 'title' => 'Request new password',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_pass'),
+ 'access callback' => 'user_is_anonymous',
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['user/reset/%/%/%'] = array(
+ 'title' => 'Reset password',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_pass_reset', 2, 3, 4),
+ 'access callback' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['user/logout'] = array(
+ 'title' => 'Log out',
+ 'access callback' => 'user_is_logged_in',
+ 'page callback' => 'user_logout',
+ 'weight' => 10,
+ 'menu_name' => 'user-menu',
+ );
+
+ // User administration pages.
+ $items['admin/user'] = array(
+ 'title' => 'User management',
+ 'description' => "Manage your site's users, groups and access to site features.",
+ 'position' => 'left',
+ 'page callback' => 'system_admin_menu_block_page',
+ 'access callback' => 'system_admin_menu_block_access',
+ 'access arguments' => array('admin/user', 'access administration pages'),
+ );
+ $items['admin/user/user'] = array(
+ 'title' => 'Users',
+ 'description' => 'List, add, and edit users.',
+ 'page callback' => 'user_admin',
+ 'page arguments' => array('list'),
+ 'access arguments' => array('administer users'),
+ );
+ $items['admin/user/user/list'] = array(
+ 'title' => 'List',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -10,
+ );
+ $items['admin/user/user/create'] = array(
+ 'title' => 'Add user',
+ 'page arguments' => array('create'),
+ 'access arguments' => array('administer users'),
+ 'type' => MENU_LOCAL_TASK,
+ );
+ $items['admin/user/settings'] = array(
+ 'title' => 'User settings',
+ 'description' => 'Configure default behavior of users, including registration requirements, e-mails, and user pictures.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_admin_settings'),
+ 'access arguments' => array('administer users'),
+ );
+
+ // Permission administration pages.
+ $items['admin/user/permissions'] = array(
+ 'title' => 'Permissions',
+ 'description' => 'Determine access to features by selecting permissions for roles.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_admin_perm'),
+ 'access arguments' => array('administer permissions'),
+ );
+ $items['admin/user/roles'] = array(
+ 'title' => 'Roles',
+ 'description' => 'List, edit, or add user roles.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_admin_new_role'),
+ 'access arguments' => array('administer permissions'),
+ );
+ $items['admin/user/roles/edit'] = array(
+ 'title' => 'Edit role',
+ 'page arguments' => array('user_admin_role'),
+ 'access arguments' => array('administer permissions'),
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['user/%user_uid_optional'] = array(
+ 'title' => 'My account',
+ 'title callback' => 'user_page_title',
+ 'title arguments' => array(1),
+ 'page callback' => 'user_view',
+ 'page arguments' => array(1),
+ 'access callback' => 'user_view_access',
+ 'access arguments' => array(1),
+ 'weight' => -10,
+ 'menu_name' => 'user-menu',
+ );
+
+ $items['user/%user/view'] = array(
+ 'title' => 'View',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -10,
+ );
+
+ $items['user/%user/cancel'] = array(
+ 'title' => 'Cancel account',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('user_cancel_confirm_form', 1),
+ 'access callback' => 'user_cancel_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['user/%user/cancel/confirm/%/%'] = array(
+ 'title' => 'Confirm account cancellation',
+ 'page callback' => 'user_cancel_confirm',
+ 'page arguments' => array(1, 4, 5),
+ 'access callback' => 'user_cancel_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_CALLBACK,
+ );
+
+ $items['user/%user/edit'] = array(
+ 'title' => 'Edit',
+ 'page callback' => 'user_edit',
+ 'page arguments' => array(1),
+ 'access callback' => 'user_edit_access',
+ 'access arguments' => array(1),
+ 'type' => MENU_LOCAL_TASK,
+ );
+
+ $items['user/%user_category/edit/account'] = array(
+ 'title' => 'Account',
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'load arguments' => array('%map', '%index'),
+ );
+
+ if (($categories = _user_categories()) && (count($categories) > 1)) {
+ foreach ($categories as $key => $category) {
+ // 'account' is already handled by the MENU_DEFAULT_LOCAL_TASK.
+ if ($category['name'] != 'account') {
+ $items['user/%user_category/edit/' . $category['name']] = array(
+ 'title callback' => 'check_plain',
+ 'title arguments' => array($category['title']),
+ 'page callback' => 'user_edit',
+ 'page arguments' => array(1, 3),
+ 'access callback' => isset($category['access callback']) ? $category['access callback'] : 'user_edit_access',
+ 'access arguments' => isset($category['access arguments']) ? $category['access arguments'] : array(1),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => $category['weight'],
+ 'load arguments' => array('%map', '%index'),
+ 'tab_parent' => 'user/%/edit',
+ );
+ }
+ }
+ }
+ return $items;
+}
+
+/**
+ * Implement 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',
+ 'file' => 'user.pages.inc',
+ ),
+ 'user_profile_category' => array(
+ 'arguments' => array('element' => NULL),
+ 'template' => 'user-profile-category',
+ 'file' => 'user.pages.inc',
+ ),
+ 'user_profile_item' => array(
+ 'arguments' => array('element' => NULL),
+ 'template' => 'user-profile-item',
+ 'file' => 'user.pages.inc',
+ ),
+ 'user_list' => array(
+ 'arguments' => array('users' => NULL, 'title' => NULL),
+ ),
+ 'user_admin_perm' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'user.admin.inc',
+ ),
+ 'user_admin_new_role' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'user.admin.inc',
+ ),
+ 'user_admin_account' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'user.admin.inc',
+ ),
+ 'user_filter_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'user.admin.inc',
+ ),
+ 'user_filters' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'user.admin.inc',
+ ),
+ 'user_signature' => array(
+ 'arguments' => array('signature' => NULL),
+ ),
+ );
+}
+
+/**
+ * Implement hook_elements().
+ */
+function user_elements() {
+ return array(
+ 'user_profile_category' => array(
+ '#theme_wrapper' => 'user_profile_category'
+ ),
+ 'user_profile_item' => array(
+ '#theme' => 'user_profile_item'
+ ),
+ );
+}
+
+/**
+ * Implement hook_fieldable_info().
+ */
+function user_fieldable_info() {
+ $return = array(
+ 'user' => array(
+ 'name' => t('User'),
+ 'id key' => 'uid',
+ ),
+ );
+ return $return;
+}
+
+/**
+ * Implement hook_field_build_modes().
+ */
+function user_field_build_modes($obj_type) {
+ $modes = array();
+ if ($obj_type == 'user') {
+ $modes = array(
+ 'full' => t('User account'),
+ );
+ }
+ return $modes;
+}
+
+/**
+ * Implement hook_hook_info().
+ */
+function user_hook_info() {
+ return array(
+ 'user' => array(
+ 'user' => array(
+ 'insert' => array(
+ 'runs when' => t('After a user account has been created'),
+ ),
+ 'update' => array(
+ 'runs when' => t("After a user's profile has been updated"),
+ ),
+ 'delete' => array(
+ 'runs when' => t('After a user has been deleted')
+ ),
+ 'login' => array(
+ 'runs when' => t('After a user has logged in')
+ ),
+ 'logout' => array(
+ 'runs when' => t('After a user has logged out')
+ ),
+ 'view' => array(
+ 'runs when' => t("When a user's profile is being viewed")
+ ),
+ ),
+ ),
+ );
+}
+
+/**
+ * Implement hook_action_info().
+ */
+function user_action_info() {
+ return array(
+ 'user_block_user_action' => array(
+ 'description' => t('Block current user'),
+ 'type' => 'user',
+ 'configurable' => FALSE,
+ 'hooks' => array(),
+ ),
+ );
+}
+
Index: modules/user/user.search.inc
===================================================================
RCS file: modules/user/user.search.inc
diff -N modules/user/user.search.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.search.inc 5 Jun 2009 21:44:43 -0000
@@ -0,0 +1,44 @@
+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;
+ }
+ }
+}
+
Index: modules/user/user.user.inc
===================================================================
RCS file: modules/user/user.user.inc
diff -N modules/user/user.user.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/user/user.user.inc 5 Jun 2009 21:45:59 -0000
@@ -0,0 +1,323 @@
+ 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.'))),
+ ),
+ );
+}
+
+/**
+ * Implement 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);
+ }
+}
+
+/**
+ * Implement 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'])));
+ }
+ }
+ }
+}
+
+/**
+ * Implement 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']);
+ }
+ }
+}
+
+/**
+ * Implement hook_user_categories().
+ */
+function user_user_categories() {
+ return array(array(
+ 'name' => 'account',
+ 'title' => t('Account settings'),
+ 'weight' => 1,
+ ));
+}
+
+/**
+ * Implement hook_user_operations().
+ */
+function user_user_operations($form_state = array()) {
+ $operations = array(
+ 'unblock' => array(
+ 'label' => t('Unblock the selected users'),
+ 'callback' => 'user_user_operations_unblock',
+ ),
+ 'block' => array(
+ 'label' => t('Block the selected users'),
+ 'callback' => 'user_user_operations_block',
+ ),
+ 'cancel' => array(
+ 'label' => t('Cancel the selected user accounts'),
+ ),
+ );
+
+ if (user_access('administer permissions')) {
+ $roles = user_roles(TRUE);
+ unset($roles[DRUPAL_AUTHENTICATED_RID]); // Can't edit authenticated role.
+
+ $add_roles = array();
+ foreach ($roles as $key => $value) {
+ $add_roles['add_role-' . $key] = $value;
+ }
+
+ $remove_roles = array();
+ foreach ($roles as $key => $value) {
+ $remove_roles['remove_role-' . $key] = $value;
+ }
+
+ if (count($roles)) {
+ $role_operations = array(
+ t('Add a role to the selected users') => array(
+ 'label' => $add_roles,
+ ),
+ t('Remove a role from the selected users') => array(
+ 'label' => $remove_roles,
+ ),
+ );
+
+ $operations += $role_operations;
+ }
+ }
+
+ // If the form has been posted, we need to insert the proper data for
+ // role editing if necessary.
+ if (!empty($form_state['submitted'])) {
+ $operation_rid = explode('-', $form_state['values']['operation']);
+ $operation = $operation_rid[0];
+ if ($operation == 'add_role' || $operation == 'remove_role') {
+ $rid = $operation_rid[1];
+ if (user_access('administer permissions')) {
+ $operations[$form_state['values']['operation']] = array(
+ 'callback' => 'user_multiple_role_edit',
+ 'callback arguments' => array($operation, $rid),
+ );
+ }
+ else {
+ watchdog('security', 'Detected malicious attempt to alter protected user fields.', array(), WATCHDOG_WARNING);
+ return;
+ }
+ }
+ }
+
+ return $operations;
+}
+
+/**
+ * Callback function for admin mass unblocking users.
+ */
+function user_user_operations_unblock($accounts) {
+ foreach ($accounts as $uid) {
+ $account = user_load($uid);
+ // Skip unblocking user if they are already unblocked.
+ if ($account !== FALSE && $account->status == 0) {
+ user_save($account, array('status' => 1));
+ }
+ }
+}
+
+/**
+ * Callback function for admin mass blocking users.
+ */
+function user_user_operations_block($accounts) {
+ foreach ($accounts as $uid) {
+ $account = user_load($uid);
+ // Skip blocking user if they are already blocked.
+ if ($account !== FALSE && $account->status == 1) {
+ user_save($account, array('status' => 0));
+ }
+ }
+}
+
+/**
+ * Callback function for admin mass adding/deleting a user role.
+ */
+function user_multiple_role_edit($accounts, $operation, $rid) {
+ // The role name is not necessary as user_save() will reload the user
+ // object, but some modules' hook_user() may look at this first.
+ $role_name = db_query('SELECT name FROM {role} WHERE rid = :rid', array(':rid' => $rid))->fetchField();
+
+ switch ($operation) {
+ case 'add_role':
+ foreach ($accounts as $uid) {
+ $account = user_load($uid);
+ // Skip adding the role to the user if they already have it.
+ if ($account !== FALSE && !isset($account->roles[$rid])) {
+ $roles = $account->roles + array($rid => $role_name);
+ user_save($account, array('roles' => $roles));
+ }
+ }
+ break;
+ case 'remove_role':
+ foreach ($accounts as $uid) {
+ $account = user_load($uid);
+ // Skip removing the role from the user if they already don't have it.
+ if ($account !== FALSE && isset($account->roles[$rid])) {
+ $roles = array_diff($account->roles, array($rid => $role_name));
+ user_save($account, array('roles' => $roles));
+ }
+ }
+ break;
+ }
+}
+
+function user_multiple_cancel_confirm(&$form_state) {
+ $edit = $form_state['input'];
+
+ $form['accounts'] = array('#prefix' => '
', '#suffix' => '
', '#tree' => TRUE);
+ // array_filter() returns only elements with TRUE values.
+ foreach (array_filter($edit['accounts']) as $uid => $value) {
+ $user = db_query('SELECT name FROM {users} WHERE uid = :uid', array(':uid' => $uid))->fetchField();
+ $form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '
', '#suffix' => check_plain($user) . "
\n");
+ }
+
+ $form['operation'] = array('#type' => 'hidden', '#value' => 'cancel');
+
+ module_load_include('inc', 'user', 'user.pages');
+ $form['user_cancel_method'] = array(
+ '#type' => 'item',
+ '#title' => t('When cancelling these accounts'),
+ );
+ $form['user_cancel_method'] += user_cancel_methods();
+ // Remove method descriptions.
+ foreach (element_children($form['user_cancel_method']) as $element) {
+ unset($form['user_cancel_method'][$element]['#description']);
+ }
+
+ // Allow to send the account cancellation confirmation mail.
+ $form['user_cancel_confirm'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Require e-mail confirmation to cancel account.'),
+ '#default_value' => FALSE,
+ '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'),
+ );
+ // Also allow to send account canceled notification mail, if enabled.
+ $form['user_cancel_notify'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Notify user when account is canceled.'),
+ '#default_value' => FALSE,
+ '#access' => variable_get('user_mail_status_canceled_notify', FALSE),
+ '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'),
+ );
+
+ return confirm_form($form,
+ t('Are you sure you want to cancel these user accounts?'),
+ 'admin/user/user', t('This action cannot be undone.'),
+ t('Cancel accounts'), t('Cancel'));
+}
+
+/**
+ * Submit handler for mass-account cancellation form.
+ *
+ * @see user_multiple_cancel_confirm()
+ * @see user_cancel_confirm_form_submit()
+ */
+function user_multiple_cancel_confirm_submit($form, &$form_state) {
+ global $user;
+
+ if ($form_state['values']['confirm']) {
+ foreach ($form_state['values']['accounts'] as $uid => $value) {
+ // Prevent user administrators from deleting themselves without confirmation.
+ if ($uid == $user->uid) {
+ $admin_form_state = $form_state;
+ unset($admin_form_state['values']['user_cancel_confirm']);
+ $admin_form_state['values']['_account'] = $user;
+ user_cancel_confirm_form_submit(array(), $admin_form_state);
+ }
+ else {
+ user_cancel($form_state['values'], $uid, $form_state['values']['user_cancel_method']);
+ }
+ }
+ }
+ $form_state['redirect'] = 'admin/user/user';
+ return;
+}
+