Hi,

do you plan on upgrading this great module to Drupal 5.x?
Would it require extensive coding or is it rather a trivial task?

Thanks,
--Josef

CommentFileSizeAuthor
#5 workspace.module.patch5.78 KBdustymugs

Comments

canadrian’s picture

Another vote for this. :)

jvandyk’s picture

Yes, this module should be upgraded. Should be easy. No time ATM though. Patches accepted.

pvasener’s picture

I did the upgrade for my personal website. Here is the resulting workspace.module file. Please be aware that it is meant to be tested and there is also a very ugly hack at the end to prevent the 'Add new content' button to appear twice.

<?php
// $Id: workspace.module,v 1.21.2.8 2006/11/28 17:38:17 jvandyk Exp $

/**
* Implementation of hook_help().
*/
function workspace_help($section) {
  $output = "";

  switch ($section) {
    case 'admin/modules#description':
    $output .= 'For individual users to manage their workspace';
    break;
  }

  return t($output);
}

/**
* Implementation of hook_menu().
*/
function workspace_menu($may_cache) {

  global $user;
  $items = array();

  $access = user_access('access content') && ($user->uid > 0);
  
  if ($may_cache) {
    $items[] = array(
      'path' => 'workspace', 
      'title' => t('my workspace'),
      'callback' => 'workspace_admin', 
      'access' => $access);

    $items[] = array(
      'path' => 'workspace/list', 
      'title' => t('list'),
      'type' => MENU_DEFAULT_LOCAL_TASK, 
      'weight' => -10);

    $items[] = array(
      'path' => 'workspace/configure', 
      'title' => t('configure'),
      'callback' => 'workspace_configure', 
      'access' => user_access('administer own workspace'),
      'type' => MENU_LOCAL_TASK);

    $items[] = array(
      'path' => 'workspace/delete', 
      'title' => t('delete'),
      'callback' => 'workspace_delete', 
      'type' => MENU_CALLBACK);
    //$items[] = array('path' => 'workspace/sharing', 'title' => t('sharing'), 'type' => MENU_LOCAL_TASK);
  }

   return $items;
}

/**
* Implementation of hook_perm().
*/
function workspace_perm() {
  return array('administer own workspace');
}

/********************************************************************
* Module Functions :: Controllers
********************************************************************/

function workspace_admin() {
  global $user;
  if (isset($_POST['content_type'])) {
    $node_type = $_POST['content_type'];
    if ($node_type == t('Select...')) {
      drupal_goto('node/add');
    }
    
    foreach (node_get_types() as $type => $typeobject) {
      if (node_access('create', $type, $user->uid)) {
        $options[$type] = $typeobject->name;
      }
      if (isset($options[$node_type])) {
        drupal_goto('node/add/' . $node_type);
      }
    }
  }

  $title = t('workspace') . ' : ' . $user->name;
  drupal_set_title($title);
  $output = workspace_list();
  return $output;
}

/**
* The configuration page.
*/
function workspace_configure_form() {
  global $user;
  $form = array();
  $form['maxnodes'] = array(
    '#type' => 'textfield',
    '#title' => t('Number of items'),
    '#description' => t('Maximum number of items to display in your workspace.'),
    '#default_value' => $user->workspaces ? $user->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' => $user->workspaces ? $user->workspaces['default']['maxfilenames'] : 50,
    '#size' => 4
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save configuration')
  );
  return $form;
}

function workspace_configure() {
  $output = drupal_get_form('workspace_configure_form');
  drupal_set_title(t('workspace : %username', array('%username' => $user->name)));
  return $output;
}

function workspace_configure_form_validate($form_id, $edit) {
  if (!is_numeric($edit['maxnodes'])) {
    form_set_error('maxnodes', t('Please enter a numeric value.'));
  }
  if (!is_numeric($edit['maxfilenames']) && !form_get_errors()) {
    form_set_error('maxfilenames', t('Please enter a numeric value.'));   
  }
}

function workspace_configure_form_submit($form_id, $edit) {
  global $user;
  if (!isset($user->workspaces)) {
    $user->workspaces = array();
  }
  $user->workspaces['default']['maxnodes'] = $edit['maxnodes'];
  $user->workspaces['default']['maxfilenames'] = $edit['maxfilenames'];
  user_save($user, array('workspaces' => $user->workspaces));
  drupal_set_message(t('The workspace configuration has been saved.'));
  return 'workspace';
}

/********************************************************************
* Module Functions :: Views
********************************************************************/

/**
* The default admin interface is a list of content.
*/
function workspace_list() {
  global $user;
  $maxnodes = isset($user->workspaces) ? $user->workspaces['default']['maxnodes'] : 50;
  $maxfilenames = isset($user->workspaces) ? $user->workspaces['default']['maxfilenames'] : 50;
  if (!is_numeric($maxnodes)) {$maxnodes = 50;}
  if (!is_numeric($maxfilenames)) {$maxfilenames = 50;}

  $comments_enabled = module_exists('comment');
  $nodeperm_role_enabled = module_exists('nodeperm_role');
  $flexinode_enabled = module_exists('flexinode');
  $cck_enabled = module_exists('content');
  $output = _workspace_addform();
  
  $node_select = array('n.nid', 'n.uid', 'n.type', '0 AS cid', 'n.title', 'n.status', 'n.changed', 's.comment_count', '1 AS node');
  $node_from = array('{node} n');
  $node_join = array('LEFT JOIN {node_comment_statistics} s ON n.nid = s.nid');
  $node_where = array('n.uid = '. db_escape_string($user->uid));

  if ($nodeperm_role_enabled) {
    $node_select[] = 'na.grant_update';
    $node_select[] = 'na.grant_delete';
    $node_join[] = 'LEFT JOIN node_access na ON n.nid = na.nid';
    $node_where[] = 'OR (na.realm = "nodeperm_role" AND na.grant_view = 1 AND na.gid IN('. db_escape_string(implode(',', array_flip($user->roles))) .'))';
  }

  $sql = 'SELECT '. implode(', ', $node_select) .' FROM '. implode(', ', $node_from) .' '. implode(' ', $node_join) .' WHERE '. implode(' ', $node_where);
  $count_sql = 'SELECT COUNT(n.nid) FROM '. implode(', ', $node_from) .' '. implode(' ', $node_join) .' WHERE '. implode(' ', $node_where);

  if ($comments_enabled) {
    $select = '';
    if ($nodeperm_role_enabled) {
      // need to add placeholders for columns to avoid misaligning our union clause
      $select = ", '' as grant_update, '' as grant_delete";
    }
    $comment_sql = 'SELECT c.nid AS cnid, c.uid, "" AS type, c.cid, c.subject, c.status, c.timestamp, c.pid, 0 '. $select .' FROM {comments} AS c, {node} n LEFT JOIN {node_comment_statistics} s ON n.nid = s.nid WHERE c.uid = '. db_escape_string($user->uid);
    $sql .= ' UNION '. $comment_sql;
    $count_sql = 'SELECT COUNT(DISTINCT(n.nid)) + COUNT(DISTINCT(c.cid)) FROM '. implode(', ', $node_from) .' '. implode(' ', $node_join) .' LEFT JOIN {comments} AS c ON c.uid = '. db_escape_string($user->uid). ' WHERE '. implode(' ', $node_where);
  }
 
   // build the combined node/comment listing
  $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'),
    $comments_enabled ? array('data' => t('Replies'), 'field' => 'comment_count') : array('data' => ''),
    array('data' => t('Operations'), 'colspan' => 2)
  );
  $result = pager_query($sql . tablesort_sql($header), $maxnodes, 0, $count_sql);
  $yes = t('yes');
  $no = t('no');
    
  while ($row = db_fetch_object($result)) {    
    // it's a node
    if ($row->node == 1) {
      // Edit and delete permissions are set by the nodetype's access hook.
      // If no access hook is found, node-level permissions are then used. 
      // This approach is part of Drupal's core design.
      $can_edit = FALSE;
      $can_delete = FALSE;
      
      //Check the nodetype's access hook.
      $function = $row->type. '_access';
      if ($flexinode_enabled && strstr($function, 'flexinode-')) {
        $function = 'flexinode_access'; 
      }
      elseif ($cck_enabled && strstr($function, 'content_')) {
        $function = 'content_access';
      } else {
        $function = 'node_access';
      }

      if (function_exists($function)) {
        $can_edit = $function('update', $row) ? TRUE : FALSE;
        $can_delete = $function('delete', $row) ? TRUE : FALSE;
      }
      elseif ($nodeperm_role_enabled) {     
        $can_edit = $row->grant_update ? TRUE : FALSE;
        $can_delete = $row->grant_delete ? TRUE : FALSE;
      }

      // 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'),
        $comments_enabled ? array('data' => $row->comment_count ? $row->comment_count : 0, 'align' => 'right') : array('data' => ''), 
        $can_edit ? l(t('edit'), "node/$row->nid/edit") : '',
        $can_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 comments.module
      $com_links = comment_links($comment, 0);
      $link = l(t('edit'), "comment/edit/$comment->cid");
      $edit_link = $com_links['comment_edit'] ? $link : '';
      
      $link = l(t('delete'), "comment/delete/$comment->cid");
      $delete_link = $com_links['comment_delete'] ? $link : '';
    
      $rows[] = array(t('comment'), l($row->title, "node/$row->nid#comment-$row->cid"), $user->name, $row->status ? $no : $yes, format_date($row->changed, 'small'), array('data' => $num_replies, 'align' => 'right'), $edit_link, $delete_link);
    }
  }

  if ($rows) {
    $pager = theme('pager', NULL, $maxnodes, 0);
    if (!empty($pager)) {
      $rows[] = array(array('data' => $pager, 'colspan' => 8));
    }
    $output .= theme('table', $header, $rows);
  }
  else {
    $output .= t('Your workspace is currently empty.');
  }

  // build the attachment listing
  $rows = array();
  $header = array(
    array('data' => t('Type'), 'field' => 'f.filemime'),
    array('data' => t('Filename'), 'field' => 'f.filename'),
    array('data' => t('Size'), 'field' => 'f.filesize')
  );

  $result = pager_query("SELECT n.nid, f.filemime, f.filename, f.filesize FROM {files} f, {node} n WHERE n.uid = $user->uid AND n.nid = f.nid" . tablesort_sql($header), $maxfilenames, 2);

  while ($row = db_fetch_object($result)) {
        $rows[] = array($row->filemime, l($row->filename, "node/$row->nid"), format_size($row->filesize));
  }

  if ($rows) {
    $output .= '<h3>' . t('Files') . '</h3>';
    $pager = theme('pager', NULL, $maxfilenames, 2);
    if (!empty($pager)) {
      $rows[] = array(array('data' => $pager, 'colspan' => 3));
    }

    $output .= theme('table', $header, $rows);
  }

  return $output;
}

/**
 * The deletion menu callback
 */
function workspace_delete() {
  $nid = intval(arg(2));
  if (is_numeric($nid)) {
    drupal_goto('node/' . $nid . '/delete');
  }
} 

/********************************************************************
* Module Functions :: Private
********************************************************************/

function _workspace_addform_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 => $typeobject) {
    if (module_invoke(node_get_types('module', $type), 'access', 'create', $type)) {
      $options[$type] = $typeobject->name;
    }
  }
  $form = array();
  $form['content_type'] = array(
    '#type' => 'select',
    '#title' => t('Add content'),
    '#options' => $options,
    '#description' => $description
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Add new item')
  );
  return $form;
}

function _workspace_addform() {
  $output = drupal_get_form('_workspace_addform_form');
  $form = _workspace_addform_form();
  $submit = drupal_render($form['submit']);
  $output = str_replace('</select>', '</select>&nbsp;' . $submit, $output);
  $output = str_replace('<input type="submit" name="op" id="edit-submit" value="Add new item"  class="form-submit" />', '', $output);
  return $output;
AmrMostafa’s picture

Status: Active » Needs work

Can you try to clean the hacks and submit a patch instead of the full module? Thanks!!

dustymugs’s picture

StatusFileSize
new5.78 KB

Thanks to groovy for doing the heavy lifting. I took his file and changed his hack to something slightly better (I think...). The diff attached should merge cleanly with workspace.module from workspace-4.7.x-1.x-dev.tar.gz.

pearcec’s picture

Can we get this checked in to HEAD. Then release a HEAD tarball that has the workspace.info file so we can test it?

jvandyk’s picture

Status: Needs work » Fixed

Committed a Drupal-5 compatible version of workspace.

Anonymous’s picture

Status: Fixed » Closed (fixed)
csc4’s picture

Where is this version? It's not listed on the project page? Is it the version in head?