'. t('The workspace module provides a list of content for each user.') .'

'; $output .= '

'. t("When enabled, each user will have a 'My workspace' link in the Navigation menu.") .'

'; return $output; } } /** * Implementation of hook_menu(). */ function workspace_menu() { $items['workspace/%user_uid_optional'] = array( 'title' => 'My workspace', 'page callback' => 'workspace_list_content', 'page arguments' => array(1), 'access callback' => 'workspace_access', 'access arguments' => array(1), 'weight' => -10, ); $items['workspace/%user/content'] = array( 'title' => 'Content', 'type' => MENU_DEFAULT_LOCAL_TASK, 'page callback' => 'workspace_list_content', 'page arguments' => array(1), 'access callback' => 'workspace_access', 'access arguments' => array(1), 'weight' => 10, ); $items['workspace/%user/comments'] = array( 'title' => 'Comments', 'type' => MENU_LOCAL_TASK, 'page callback' => 'workspace_list_comments', 'page arguments' => array(1), 'access callback' => 'workspace_access', 'access arguments' => array(1, module_exists('comment')), 'weight' => 20, ); $items['workspace/%user/attachments'] = array( 'title' => 'Attachments', 'type' => MENU_LOCAL_TASK, 'page callback' => 'workspace_list_files', 'page arguments' => array(1), 'access callback' => 'workspace_access', 'access arguments' => array(1, module_exists('upload')), 'weight' => 30, ); $items['workspace/%user/configure'] = array( 'title' => 'Configure', 'page callback' => 'workspace_configure', 'page arguments' => array(1), 'access callback' => 'workspace_configure_access', 'access arguments' => array(1), 'type' => MENU_LOCAL_TASK, 'weight' => 50, ); $items['admin/settings/workspace'] = array( 'title' => 'Workspace', 'description' => 'Customize workspace behavior.', 'page callback' => 'drupal_get_form', 'page arguments' => array('workspace_settings'), 'access arguments' => array('administer workspaces'), ); // In this entry, 'access content' permission may seem liberal // but since workspace_delete() simply redirects to // node/*/delete deletion permissions will be applied there. $items['workspace/delete'] = array( 'title' => 'Delete', 'page callback' => 'workspace_delete', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * Menu access callback. */ function workspace_access($account, $module_enabled = TRUE) { global $user; // Let admin see $account if ($user->uid == 1 && $account->uid > 1) { return user_access('access content', $account) && user_access('access workspace', $account) && $module_enabled; } return user_access('access content', $user) // If you may not see content, you may not see workspaces. && user_access('access workspace', $user) // Allowed to see own workspace && (user_access('view all workspaces', $user) // Must either have permission to see all workspaces || (($user->uid == $account->uid) // or must be your workspace && ($user->uid != 0))) // and you must not be an anonymous user && $module_enabled; // If, e.g., comment module is disabled, remove comment local task. } /** * Menu access callback. */ function workspace_configure_access($account) { global $user; if ($user->uid == 1 && $account->uid > 1) { return user_access('administer workspaces', $account) || user_access('administer own workspace', $account); } return ($user->uid != 0) // May not be anonymous user. && user_access('administer workspaces') // Must either have permission to administer all workspaces || ($user->uid == $account->uid // Or if this is your workspace && user_access('administer own workspace') // you must have 'administer own workspace' permission ); } /** * Implementation of hook_perm(). */ function workspace_perm() { return array('access workspace', 'administer own workspace', 'administer workspaces', 'view all workspaces'); } /** * Menu callback. The configuration page. */ function workspace_configure($account) { drupal_set_title(t('Workspace: @name', array('@name' => $account->name))); $output = drupal_get_form('workspace_configure_form', $account); return $output; } /** * Form definition for per-user configuration form. */ function workspace_configure_form($form_state, $account) { $form['maxnodes'] = array( '#type' => 'textfield', '#title' => t('Number of items'), '#description' => t('Maximum number of items to display in your workspace.'), '#default_value' => $account->workspaces ? $account->workspaces['default']['maxnodes'] : 50, '#size' => 4 ); $form['maxfilenames'] = array( '#type' => 'textfield', '#title' => t('Number of files'), '#description' => t('Maximum number of filenames to display in your workspace.'), '#default_value' => $account->workspaces ? $account->workspaces['default']['maxfilenames'] : 50, '#size' => 4 ); if ( module_exists('comment') ) { $form['maxcomments'] = array( '#type' => 'textfield', '#title' => t('Number of comments'), '#description' => t('Maximum number of comments to display in your workspace.'), '#default_value' => $account->workspaces['default']['maxcomments'] ? $account->workspaces['default']['maxcomments'] : 50, '#size' => 4 ); } $form['uid'] = array( '#type' => 'value', '#value' => $account->uid, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Save configuration') ); return $form; } /** * Validator for per-user configuration form. * * @see workspace_configure_form() */ function workspace_configure_form_validate($form, $form_state) { if (!is_numeric($form_state['values']['maxnodes'])) { form_set_error('maxnodes', t('Please enter a numeric value.')); } if (!is_numeric($form_state['values']['maxfilenames']) && !form_get_errors()) { form_set_error('maxfilenames', t('Please enter a numeric value.')); } if ( module_exists('comment') ) { if (!is_numeric($form_state['values']['maxcomments']) && !form_get_errors()) { form_set_error('maxcomments', t('Please enter a numeric value.')); } } } /** * Submit handler for per-user configuration form. * * @see workspace_configure_form() */ function workspace_configure_form_submit($form, &$form_state) { // Must do a full user load to get existing serialized data. $account = user_load(array('uid' => $form_state['values']['uid'])); if (!isset($account->workspaces)) { $account->workspaces = array(); } $account->workspaces['default']['maxnodes'] = (int)$form_state['values']['maxnodes']; $account->workspaces['default']['maxfilenames'] = (int)$form_state['values']['maxfilenames']; if ( module_exists('comment') ) { $account->workspaces['default']['maxcomments'] = (int)$form_state['values']['maxcomments']; } user_save($account, array('workspaces' => $account->workspaces)); drupal_set_message(t('The workspace preferences have been saved.')); $form_state['redirect'] = 'workspace/'. $form_state['values']['uid']; } /** * Menu callback. Display list of content. * * @param $account * User object representing user whose workspace is being listed. */ function workspace_list_content($account) { global $user; drupal_set_title(t('Workspace: @name', array('@name' => $account->name))); $max = isset($user->workspaces) ? $user->workspaces['default']['maxnodes'] : 50; $comments_enabled = module_exists('comment'); if ($comments_enabled) { // If the comment module is enabled, we need to get comment counts too. $sql = 'SELECT n.nid, n.uid, n.type, 0 as cid, n.title, n.status, n.changed, s.comment_count, 1 as node FROM {node} n LEFT JOIN {node_comment_statistics} s ON n.nid = s.nid WHERE n.uid = %d'; $count_sql = 'SELECT COUNT(n.nid) FROM {node} n LEFT JOIN {node_comment_statistics} s ON n.nid = s.nid WHERE n.uid = %d'; $header = array( array('data' => t('Type'), 'field' => 'type'), array('data' => t('Title'), 'field' => 'title'), array('data' => t('Owner'), 'field' => 'uid'), array('data' => t('Published'), 'field' => 'status'), array('data' => t('Modified'), 'field' => 'changed', 'sort' => 'desc'), array('data' => t('Replies'), 'field' => 'comment_count'), array('data' => t('Operations'), 'colspan' => 2) ); } else { // Otherwise we use a simpler query. $sql = 'SELECT n.nid, n.uid, n.type, 0 as cid, n.title, n.status, n.changed, 1 as node FROM {node} n WHERE n.uid = %d'; $count_sql = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.uid = %d'; $header = array( array('data' => t('Type'), 'field' => 'type'), array('data' => t('Title'), 'field' => 'title'), array('data' => t('Owner'), 'field' => 'uid'), array('data' => t('Published'), 'field' => 'status'), array('data' => t('Modified'), 'field' => 'changed', 'sort' => 'desc'), array('data' => t('Operations'), 'colspan' => 2) ); } $cols = 8; $result = pager_query(db_rewrite_sql($sql . tablesort_sql($header)), $max, 0, db_rewrite_sql($count_sql), $account->uid); $rows = workspace_build_rows($result, $account); $output = ''; // Only add the content add form if the user is viewing his/her own workspace. if ($user->uid == 1 || user_access('view all workspaces') || $user->uid == $account->uid) { $output = drupal_get_form('workspace_add_form'); } $output .= theme('workspace_list', $header, $rows, $max, $cols); return $output; } /** * Menu callback. Display list of comments. * * @param $account * User object representing user whose workspace is being listed. */ function workspace_list_comments($account) { drupal_set_title(t('Workspace: @name', array('@name' => $account->name))); $max = isset($account->workspaces) ? $account->workspaces['default']['maxcomments'] : 50; $sql = 'SELECT c.nid, c.uid, c.cid, c.subject, c.status, c.timestamp, c.pid, 0 FROM {comments} c WHERE c.uid = %d'; $count_sql = 'SELECT COUNT(cid) FROM {comments} WHERE uid = %d'; // Build the comment listing. $header = array( array('data' => t('Title'), 'field' => 'title'), array('data' => t('Published'), 'field' => 'status'), array('data' => t('Modified'), 'field' => 'timestamp', 'sort' => 'desc'), array('data' => t('Replies'), 'field' => 'comment_count'), array('data' => t('Operations'), 'colspan' => 2) ); $cols = 6; $result = pager_query($sql . tablesort_sql($header), $max, 0, $count_sql, $account->uid); $rows = workspace_build_rows($result, $account); return theme('workspace_list', $header, $rows, $max, $cols); } /** * Build the query result into a table, respecting access. * * @param $result * A result object as returned from pager_query(). * @param $account * User object representing user whose workspace is being listed. */ function workspace_build_rows($result, $account) { global $user; $yes = t('yes'); $no = t('no'); $rows = array(); while ($row = db_fetch_object($result)) { // It's a node. if ($row->node == 1) { // Edit and delete permissions are set by the node type's access hook. // If no access hook is found, node-level permissions are then used. // This approach is part of Drupal's core design. $may_edit = FALSE; $may_delete = FALSE; //Check the node type's access hook. $function = $row->type .'_access'; if ($cck_enabled && strstr($function, 'content_')) { $function = 'content_access'; } else { $function = 'node_access'; } if (function_exists($function)) { if (!$function('view', $row, $user)) { // No view permission means it is not shown in the workspace. continue; } $may_edit = $function('update', $row, $user) ? TRUE : FALSE; $may_delete = $function('delete', $row, $user) ? TRUE : FALSE; } else { // If we can't find an access function, deny by default. continue; } // The name of the owner of this node. $name = ($user->uid == $row->uid) ? $user->name : db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $row->uid)); $rows[] = array( node_get_types('name', $row->type), l($row->title, "node/$row->nid"), $name, $row->status ? $yes : $no, format_date($row->changed, 'small'), module_exists('comment') ? array('data' => $row->comment_count ? $row->comment_count : 0, 'align' => 'right') : array('data' => ''), $may_edit ? l(t('edit'), "node/$row->nid/edit") : '', $may_delete ? l(t('delete'), "workspace/delete/$row->nid") : '' ); } else { // It's a comment. $num_replies = comment_num_replies($row->cid); $comment->cid = $row->cid; $comment->nid = $row->nid; // Delegate access permission checks and link generation to comment.module. $comment_links = comment_links($comment, 0); $link = l(t('edit'), "comment/edit/$comment->cid"); $edit_link = $comment_links['comment_edit'] ? $link : ''; $link = l(t('delete'), "comment/delete/$comment->cid"); $delete_link = $comment_links['comment_delete'] ? $link : ''; $rows[] = array( l($row->subject, "node/$row->nid", array(), NULL, "comment-$row->cid", FALSE, TRUE), $row->status ? $no : $yes, format_date($row->timestamp, 'small'), array('data' => $num_replies, 'align' => 'right'), $edit_link, $delete_link, ); } } return $rows; } /** * Menu callback. List file attachments managed by upload.module. * * @param $account * User object representing user whose workspace is being listed. */ function workspace_list_files($account) { global $user; drupal_set_title(t('Workspace: @name', array('@name' => $account->name))); $max = isset($user->workspaces) ? $user->workspaces['default']['maxfilenames'] : 50; $download = t('download'); $rows = array(); $header = array( array('data' => t('Filename'), 'field' => 'f.filename'), array('data' => t('Type'), 'field' => 'f.filemime'), array('data' => t('Modified'), 'field' => 'f.timestamp', 'sort' => 'desc'), array('data' => t('Size'), 'field' => 'f.filesize'), array('data' => t('Operations')), ); $cols = 6; $sql = "SELECT u.nid, f.filemime, f.filename, f.filesize, f.timestamp, f.filepath FROM {files} f LEFT JOIN {upload} u ON f.fid = u.fid WHERE f.uid = %d"; $result = pager_query($sql . tablesort_sql($header), $max, 2, NULL, $account->uid); while ($row = db_fetch_object($result)) { $rows[] = array( l($row->filename, "node/$row->nid"), $row->filemime, format_date($row->timestamp, 'small'), format_size($row->filesize), l($download, file_create_url($row->filepath)), ); } return theme('workspace_list', $header, $rows, $max, $cols); } /** * Implementation of hook_theme(). */ function workspace_theme() { return array( 'workspace_list' => array( 'arguments' => array('header' => array(), 'rows' => array(), $max = 50, $cols = 8), ), ); } /** * Theme the list of content. Turn the results into a table. */ function theme_workspace_list($header, $rows, $max, $cols) { if ($rows) { $pager = theme('pager', NULL, $max); if (!empty($pager)) { $rows[] = array(array('data' => $pager, 'colspan' => $cols)); } $output = theme('table', $header, $rows); } else { $output = t('Your workspace is currently empty.'); } return $output; } /** * Menu callback. Redirect user to delete node. */ function workspace_delete() { $nid = intval(arg(2)); if (is_numeric($nid)) { drupal_goto('node/'. $nid .'/delete'); } } /** * Form definition for content addition form. */ function workspace_add_form() { global $user; $description = t('Choose what kind of content you would like to add.') .' '. l(t('Help?'), 'node/add'); $select = t('Select...'); $options = array($select => $select); foreach (node_get_types() as $type => $object) { if (module_invoke(node_get_types('module', $type), 'access', 'create', $type, $user)) { $options[$type] = $object->name; } } if (count($options) == 1) { return array(); } $form['add'] = array( '#type' => 'fieldset', '#prefix' => '
', '#suffix' => '
', ); $form['add']['content_type'] = array( '#type' => 'select', '#options' => $options, ); $form['add']['submit'] = array( '#type' => 'submit', '#value' => t('Add new item'), '#suffix' => $description, ); return $form; } /** * Submit handler for content addition form. * * Simply redirects to appropriate node/add/* page. * * @see workspace_add_form() */ function workspace_add_form_submit($form, $form_state) { $node_type = $form_state['values']['content_type']; if ($node_type == t('Select...')) { drupal_goto('node/add'); } foreach (node_get_types() as $type => $object) { if (node_access('create', $type, $user->uid)) { $options[$type] = $object->name; } if (isset($options[$node_type])) { /* Start hack */ if (stristr($node_type, "_") > -1) { $node_type = str_replace("_", "-", $node_type); } /* End hack */ drupal_goto('node/add/'. $node_type); } } } /** * Implementation of hook_settings(). */ function workspace_settings() { $roles = user_roles(); // The anonymous user does not have a profile. unset($roles[DRUPAL_ANONYMOUS_RID]); $form['info'] = array( '#value' => t("Select each role for which you want the link to a user's workspace to show up in their user profile."), ); foreach ($roles as $rid => $name) { $identifier = 'workspace_user_profile_'. $rid; $form[$identifier] = array( '#type' => 'checkbox', '#title' => $name, '#default_value' => variable_get($identifier, 0), ); } $form['workspace_user_profile_link'] = array( '#type' => 'textfield', '#title' => t("Name of link to user's workspace"), '#description' => t("This will be used to display the link to a user's workspace on his or her profile page. The %username token will be replaced by the username of the user whose profile is being shown."), '#default_value' => variable_get('workspace_user_profile_link', t('View recent content created by %username')), ); return system_settings_form($form); } /** * Implementation of hook_user(). * * Place link to user's workspace on user's profile page. */ function workspace_user($op, &$edit, &$account) { global $user; if ($op == 'view') { if (workspace_access($account)) { $variables['%username'] = $account->name; $link_title = variable_get('workspace_user_profile_link', t('View recent content')); $link = l(strtr($link_title, $variables), 'workspace/'. $account->uid); $account->content['workspace'] = array( '#type' => 'user_profile_category', '#title' => variable_get('workspace_user_profile_title', t('Content')), 'link' => array( '#value' => $link, '#type' => 'user_profile_item', ), '#weight' => -10, ); } } }