diff -ru webfm-6.x-2.9-alpha2/js/webfm.js webfm/js/webfm.js
--- webfm-6.x-2.9-alpha2/js/webfm.js 2008-04-08 08:28:14.000000000 +0200
+++ webfm/js/webfm.js 2008-08-16 11:32:00.000000000 +0200
@@ -92,6 +92,8 @@
Webfm.menu_msg["ren"] = "Rename File";
Webfm.menu_msg["meta"] = "File meta data";
Webfm.menu_msg["att"] = "Attach to Node";
+Webfm.menu_msg["attdir"] = "Attach all Files in Folder to Node";
+Webfm.menu_msg["unzip"] = "Extract to here";
Webfm.menu_msg["det"] = "Detach from Node";
Webfm.menu_msg["dwnld"] = "Download as file";
Webfm.menu_msg["view"] = "View file";
@@ -297,6 +299,7 @@
//Add attach-list menu and attach option to listing menu
try {
Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["att"], Webfm.menuAttach, Webfm.menuFidVal));
+ Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["attdir"], Webfm.menuAttachDir, Webfm.menuFidVal));
Webfm.menuHT.put('det', new Webfm.menuElement(Webfm.menu_msg["meta"], Webfm.menuGetMeta, ''));
Webfm.menuHT.put('det', new Webfm.menuElement(Webfm.menu_msg["det"], Webfm.menuDetach, ''));
} catch(err) {
@@ -346,12 +349,16 @@
//global to allow external functions to push new menu elements into the menu array
Webfm.menuHT = new Webfm.hht();
try {
- Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.menuAdmin));
+ //Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.menuAdmin));
+ Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, ''));
Webfm.menuHT.put('root', new Webfm.menuElement(Webfm.menu_msg["search"], Webfm.menuSearch, ''));
- Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.menuAdmin));
- Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rmdir"], Webfm.menuRemove, Webfm.menuAdmin));
- Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rendir"], Webfm.menuRename, Webfm.menuAdmin));
+ //Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, Webfm.menuAdmin));
+ //Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rmdir"], Webfm.menuRemove, Webfm.menuAdmin));
+ //Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rendir"], Webfm.menuRename, Webfm.menuAdmin));
+ Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["mkdir"], Webfm.menuMkdir, ''));
+ Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rmdir"], Webfm.menuRemove, ''));
+ Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["rendir"], Webfm.menuRename, ''));
Webfm.menuHT.put('dir', new Webfm.menuElement(Webfm.menu_msg["search"], Webfm.menuSearch, ''));
Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["rm"], Webfm.menuRemove, Webfm.menuFileUid));
@@ -362,7 +369,8 @@
Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["enum"], Webfm.menuInsert, Webfm.menuAdminNoFidVal));
Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["denum"], Webfm.menuDbRem, Webfm.menuAdminFidVal));
Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["perm"], Webfm.menuGetPerm, Webfm.menuFilePerm));
- Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["clip"], Webfm.menuPutLinkInClipboard, Webfm.menuFidVal))
+ Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["clip"], Webfm.menuPutLinkInClipboard, Webfm.menuFidVal));
+ Webfm.menuHT.put('file', new Webfm.menuElement(Webfm.menu_msg["unzip"], Webfm.menuUnzip, Webfm.menuZipVal));
} catch(err) {
alert("Menu Create err\n" + err);
}
@@ -1793,6 +1819,25 @@
}
}
+// Attach all files in directory to node
+Webfm.menuAttachDir = function(obj) {
+ files = Webfm.dirListObj.content.files;
+ for(item in files) {
+ obj.clickObj.title = files[item]['id'];
+ Webfm.menuAttach(obj);
+ }
+}
+
+// Unzip ZIP-Archive
+Webfm.menuUnzip = function(obj) {
+ var url = Webfm.ajaxUrl();
+ Webfm.progressObj.show(Webfm.js_msg["work"], "blue");
+ var path = obj.element.title;
+ path = path.substring(0, path.lastIndexOf("/"));
+ var postObj = { action:encodeURIComponent("unzip"), param0:encodeURIComponent(obj.clickObj.title) };
+ Webfm.HTTPPost(url, Webfm.dbrem_callback, path, postObj);
+}
+
Webfm.menuDetach = function(obj) {
Webfm.alrtObj.msg();
var path = obj.element.title;
@@ -1957,6 +2002,13 @@
return false;
}
+Webfm.menuZipVal = function(obj) {
+ if(obj.fmime == 'application/zip')
+ return true;
+ //return false;
+ return true;
+}
+
Webfm.confirm = function(text) {
var agree = confirm(text);
return agree ? true : false;
@@ -2461,9 +2513,21 @@
Webfm.attach.prototype.fetch = function() {
var url = Webfm.ajaxUrl();
// action attribute of node-edit form contains the node number
- var node_url = Webfm.$('node-form').action;
+ var node_url;
+ if(Webfm.$('node-form')) {
+ node_url = Webfm.$('node-form').action;
+ }
+ if(Webfm.$('comment-form')) {
+ node_url = Webfm.$('comment-form').action;
+ }
Webfm.progressObj.show(Webfm.js_msg["work"], "blue");
var postObj = { action:encodeURIComponent("attach"), param0:encodeURIComponent(node_url) };
+ // If we are in a preview/validate, the fids are still stored in the form.
+ // Pass them to webfm_ajax to reload them.
+ var fids = Webfm.$(Webfm.attachFormInput).value;
+ if (fids.length != 0) {
+ postObj.param1 = encodeURIComponent(fids);
+ }
Webfm.HTTPPost(url, this.callback, this, postObj);
}
@@ -2476,9 +2540,20 @@
if(result.data.length) {
Webfm.admin = result.admin;
var elInput = Webfm.$(Webfm.attachFormInput);
+ var attach_arr = [];
+ attach_arr = Webfm.$(Webfm.attachFormInput).value.split(',');
+ Webfm.current = null;
for(var i = 0; i < result.data.length; i++) {
var filerow = new Webfm.filerow(obj.body, result.data[i], 'attach', '', true, Webfm.menuHT.get('det'), obj.eventListeners);
- elInput.setAttribute('value', (elInput.getAttribute('value')?elInput.getAttribute('value')+',':'') + result.data[i].id);
+ // Don't add if it already exists.
+ // Note that values are kept in the form for preview/failed validate.
+ for (var j = 0; j < attach_arr.length; j++) {
+ if (result.data[i].id == attach_arr[j])
+ break;
+ }
+ if (j == attach_arr.length) {
+ elInput.setAttribute('value', (elInput.getAttribute('value')?elInput.getAttribute('value')+',':'') + result.data[i].id);
+ }
}
}
} else
@@ -3505,6 +3580,7 @@
var toSend = '';
if (typeof object == 'object') {
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xmlHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
for (var i in object) {
toSend += (toSend ? '&' : '') + i + '=' + encodeURIComponent(object[i]);
}
diff -ru webfm-6.x-2.9-alpha2/webfm.install webfm/webfm.install
--- webfm-6.x-2.9-alpha2/webfm.install 2008-04-08 08:28:14.000000000 +0200
+++ webfm/webfm.install 2008-07-27 13:06:00.000000000 +0200
@@ -76,12 +76,27 @@
'nid' => array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'default' => 0),
'fid' => array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'default' => 0),
'weight' => array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'default' => 0),
+ 'cid' => array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, 'default' => 0),
),
- 'primary key' => array('nid', 'fid'),
+ 'primary key' => array('nid', 'fid', 'cid' ),
);
return $schema;
}
+/**
+ * Add column for comment id in webfm_attach table.
+ */
+function webfm_update_1() {
+ $ret = array();
+ // Add the new colum to store a comment id.
+ db_add_field($ret, 'webfm_attach', 'cid', array('type' => 'int', 'not null' => TRUE, 'default' => '0'));
+
+ // Make it a primary key.
+ db_drop_primary_key($ret, 'webfm_attach');
+ db_add_primary_key($ret, 'webfm_attach', array('nid', 'cid', 'fid'));
+ return $ret;
+}
+
// switch ($GLOBALS['db_type']) {
// case 'mysql':
diff -ru webfm-6.x-2.9-alpha2/webfm.module webfm/webfm.module
--- webfm-6.x-2.9-alpha2/webfm.module 2008-04-23 17:50:06.000000000 +0200
+++ webfm/webfm.module 2008-08-16 11:27:00.000000000 +0200
@@ -156,6 +156,7 @@
function webfm_admin_settings_validate($form, $form_state) {
$valid_webfm_root = FALSE;
$webfm_root_dir_name = $form_state['values']['webfm_root_dir'];
+
if(!empty($webfm_root_dir_name)) {
if(!preg_match('/^[0-9a-zA-Z]/', $webfm_root_dir_name)) {
form_set_error('webfm_root_dir'. $rid, t('The leading character of the webfm root directory name must be alphanumeric.'));
@@ -167,6 +168,32 @@
}
}
+///////////////////////////////////////////////////////////////////////////////
+
+ $valid_user_root = FALSE;
+ // Allow tokenized paths.
+ if (function_exists('token_replace')) {
+ // Validate with current user...
+ global $user;
+ $webfm_user_dir_name = token_replace($form_state['values']['webfm_user_dir'], 'user', $user);
+ }
+ else {
+ $webfm_user_dir_name = $form_state['values']['webfm_user_dir'];
+ }
+
+ if(!empty($webfm_user_dir_name)) {
+ if(!preg_match('/^[0-9a-zA-Z]/', $webfm_user_dir_name)) {
+ form_set_error('webfm_user_dir'. $rid, t('The leading character of the webfm user directory name must be alphanumeric.'));
+ } else if(preg_match('[\.]', $webfm_user_dir_name)) {
+ form_set_error('webfm_user_dir'. $rid, t('The webfm user directory name is not valid.'));
+ } else {
+ $webfm_user_dir = $webfm_root_dir ."/".$webfm_user_dir_name;
+ $valid_webfm_user = file_check_directory($webfm_user_dir, FILE_CREATE_DIRECTORY, 'webfm_user_dir');
+ }
+ }
+
+///////////////////////////////////////////////////////////////////////////////
+
if(($form_state['values']['webfm_max_resolution'] != '0')) {
if(!preg_match('/^[0-9]+[xX][0-9]+$/', $form_state['values']['webfm_max_resolution'])) {
form_set_error('webfm_max_resolution', t('The maximum allowed image size expressed as WIDTHxHEIGHT (e.g. 640x480). Set to 0 for no restriction.'));
@@ -180,7 +207,7 @@
$uploadsize = $form_state['values']['webfm_uploadsize_'. $rid];
$usersize = $form_state['values']['webfm_usersize_'. $rid];
$role_root_dir_name = $form_state['values']['root_dir_'.$rid];
-
+
if(!empty($role_root_dir_name)) {
if($valid_webfm_root) {
if(!preg_match('/^[0-9a-zA-Z]/', $role_root_dir_name)) {
@@ -232,6 +259,25 @@
exist for this setting to validate (ie: path/to).')
);
+
+ $form['webfm_user_dir'] =
+ array('#type' => 'textfield',
+ '#title' => t('WebFM user directory'),
+ '#default_value' => variable_get('webfm_user_dir', ''),
+ '#maxlength' => '100',
+ '#size' => '70',
+ '#description' => t('Root directory for users.
+
This path is relative to "WebFM root directory" path.
+
If this directory path is compound (ie: path/to/user) then the path must already
+
exist for this setting to validate (ie: path/to).')
+
+ );
+
+ if (function_exists('token_replace')) {
+ $form['webfm_user_dir']['#description'] .= ' '. t('You can use the following tokens:');
+ $form['webfm_user_dir']['#suffix'] = theme('token_help', 'user');
+ }
+
$form['webfm_icon_dir'] =
array('#type' => 'textfield',
'#title' => t('Icon directory'),
@@ -339,7 +385,9 @@
'#default_value' => variable_get("webfm_extensions_".$rid, "jpg jpeg gif png txt html htm doc xls pdf ppt pps"),
'#maxlength' => 255,
'#description' => t('Extensions that users in this role can upload. Separate extensions with a space
-
and do not include the leading dot.')
+
and do not include the leading dot.
+
Enter * to accept all extensions.'),
+
);
$form["settings_role_".$rid]["webfm_uploadsize_".$rid] =
@@ -542,9 +590,96 @@
}
/**
+ * Implementation of hook_comment().
+ *
+ * Similar to webfm_nodeapi, but for comments instead of nodes.
+ * Note: Enabling webfm in the edit form is done in form_alter. Keeping the
+ * attachments while preview or a failing form_validate is done by form_alter
+ * and webfm_ajax.
+ * webfm_comment is only needed to save the attachments to the table and
+ * for viewing and previewing comments.
+ * We don't need to initialize js in 'validate' here because a failing form
+ * validation re-initializes the whole node, including js.
+ */
+function webfm_comment(&$comment, $op) {
+ if (is_object($comment)) {
+ $cid = $comment->cid;
+ $nid = $comment->nid;
+ }
+ else {
+ $cid = $comment['cid'];
+ $nid = $comment['nid'];
+ }
+
+ # We need the parent node for checking its permission to view attachments etc.
+ $node = node_load($nid);
+
+ switch ($op) {
+ case 'view':
+ if (variable_get("wfm_attach_$node->type", 1) == 1 &&
+ user_access('view webfm attachments') &&
+ variable_get('webfm_attach_body', '')) {
+ // If we preview a comment, $comment->preview is defined because the preview button
+ // for comments is added with $form['preview']. Thus we know that $_POST['attachlist']
+ // is ours. If we are previewing another comment and just "view" this one,
+ // the preview flag is not set and $_POST['attachlist'] belongs to someone else.
+ // This happens when previewing or editing a comment and the node and/or
+ // other comments might be shown, too.
+ // If we preview without 'acces webfm' permissions, we fetch from database,
+ // cf. nodeapi below.
+ if ($comment->preview && user_access('access webfm')) {
+ if ($_POST['attachlist']) {
+ $show_files = webfm_get_temp_attachments($_POST['attachlist']);
+ }
+ }
+ else {
+ // Normal view. Try to load attachments. There is no 'load' op for hook_comment.
+ if (!isset($comment->webfm_files)) {
+ $comment->webfm_files = webfm_get_attachments($cid, 'cid');
+ }
+ if (is_array($comment->webfm_files) && count($comment->webfm_files)) {
+ $show_files = $comment->webfm_files;
+ }
+ }
+ if ($show_files) {
+ $comment->comment .= theme('webfm_attachments', $show_files);
+ drupal_add_css(drupal_get_path('module', 'webfm').'/css/webfm.css');
+ }
+ }
+ break;
+
+ case 'insert':
+ if ($_POST['attachlist']) {
+ $files = explode(',', $_POST['attachlist']);
+ $i = 0;
+ foreach ($files as $fid) {
+ if ($fid)
+ // weight argument determined by position in csv
+ webfm_dbinsert_attach(0, $fid, $i++, $cid);
+ }
+ }
+ break;
+
+ case 'update':
+ // If the user cannot access webfm, $_POST['attachlist'] is always empty
+ // and therefore will delete existing attachments from the node.
+ if (user_access('access webfm')) {
+ $files = explode(',', $_POST['attachlist']);
+ webfm_dbupdate_attach(0, $files, $cid);
+ }
+ break;
+
+ case 'delete':
+ webfm_dbdelete_attachments($cid, 'cid');
+ break;
+ }
+}
+
+/**
* Implementation of hook_nodeapi().
*/
function webfm_nodeapi(&$node, $op, $teaser) {
+ global $user;
switch ($op) {
case 'load':
if ((variable_get("wfm_attach_$node->type", 1) == 1) &&
@@ -555,19 +690,61 @@
break;
case 'view':
- // Add the attachments list to node body if configured to appear in body
- if (is_array($node->webfm_files) && variable_get('webfm_attach_body', '')) {
- if (count($node->webfm_files) && !$teaser) {
+ // Add the attachments list to node body if configured to appear in body.
+ if (variable_get('webfm_attach_body', '')) {
+ // We could be viewing or previewing this node.
+ // Loading a node defines $node->webfm_files, possibly as empty list,
+ // but loading an edit form unsets $node->webfm_files again. Thus, if
+ // $node->webfm is not set, we are previewing this node.
+ // Two cases then:
+ // 1) The user has no webfm access rights, so he can't change anything
+ // and $_POST['attachlist'] is empty. Simulate the 'load' operation
+ // to get the files from the database to show them in the preview.
+ // 2) If user has webfm access, all attachments (saved/unsaved)
+ // are in $_POST['attachlist']. But $_POST['attachlist'] is also set if
+ // we preview e.g. a comment where this node is shown, too, but then
+ // the attachlist is not ours. So we check for webfm_files *before*
+ // checking for $_POST to get around this.
+ if (!user_access('access webfm') && (variable_get("wfm_attach_$node->type", 1) == 1)
+ && user_access('view webfm attachments')) {
+ $node->webfm_files = webfm_get_attachments($node->nid);
+ }
+ if (is_array($node->webfm_files)) {
+ if (count($node->webfm_files) && !$teaser) {
+ $show_files = $node->webfm_files;
+ }
+ }
+ // We must check for view permissions in a preview, but wfm_attach_$node->type
+ // is true if we already have attachments here.
+ elseif ($_POST['attachlist'] && user_access('view webfm attachments')) {
+ $show_files = webfm_get_temp_attachments($_POST['attachlist']);
+ }
+ if ($show_files) {
$node->content['webfm_attachments'] = array(
- '#value' => theme('webfm_attachments', $node->webfm_files),
+ '#value' => theme('webfm_attachments', $show_files),
'#weight' => 10,
- );
+ );
drupal_add_css(drupal_get_path('module', 'webfm').'/css/webfm.css');
}
}
break;
+ case 'validate':
+ // When form_validate fails for preview or save, we must reinitialize
+ // javascript, otherwise webfm doesn't work anymore.
+ $modulepath = drupal_get_path('module', 'webfm');
+ drupal_add_js($modulepath .'/js/webfm.js');
+ drupal_add_css($modulepath .'/css/webfm.css');
+ if (is_null($inline_js)) {
+ $clean_url = variable_get('clean_url', 0);
+ $clean = (($clean_url == 0) || ($clean_url == '0')) ? FALSE : TRUE;
+ $inline_js = webfm_inline_js($base_url, $clean, $user->uid);
+ }
+ break;
+
case 'insert':
+ // We saved the attachment list for preview. Remove before saving.
+ unset($node->attachlist);
if($_POST['attachlist']) {
$files = explode(',', $_POST['attachlist']);
$i = 0;
@@ -580,8 +757,26 @@
break;
case 'update':
- $files = explode(',', $_POST['attachlist']);
- webfm_dbupdate_attach($node->nid, $files);
+ // We saved the attachment list for preview. Remove before saving.
+ unset($node->attachlist);
+ // If the user cannot access webfm, $_POST['attachlist'] is always empty
+ // and therefore will delete existing attachments from the node.
+ if(user_access('access webfm')) {
+ /*
+ $orderfiles = webfm_get_attachments($node->nid);
+ usort($orderfiles, function cmp($a, $b){ return strcmp($a->n, $b->n);});
+ $files = array();
+ foreach($orderfiles as $file) {
+ $files[] = $file->id;
+ }
+ */
+ $files = explode(',', $_POST['attachlist']);
+ webfm_dbupdate_attach($node->nid, $files);
+ }
+ break;
+
+ case 'delete':
+ webfm_dbdelete_attachments($node->nid);
break;
}
}
@@ -607,12 +802,17 @@
);
}
- if (isset($form['type'])) {
- $node = $form['#node'];
- if ($access &&
- $form['type']['#value'] .'_node_form' == $form_id &&
- variable_get('webfm_attach_'.$node->type, 0)) {
-
+ if (isset($form['type']) || $form_id == 'comment_form') {
+ // For a comment form, the webfm permissions are inherited from the comments node.
+ if ($form_id == 'comment_form') {
+ $node = node_load($form['nid']['#value']);
+ $formcheck = TRUE;
+ }
+ else {
+ $node = $form['#node'];
+ $formcheck = ($form['type']['#value'] .'_node_form' == $form_id);
+ }
+ if ($access && $formcheck && variable_get('webfm_attach_'. $node->type, 0)) {
$modulepath = drupal_get_path('module', 'webfm');
drupal_add_js($modulepath.'/js/webfm.js');
drupal_add_css($modulepath.'/css/webfm.css');
@@ -703,11 +903,24 @@
function webfm_attach_attached_form($node) {
$form['#theme'] = 'webfm_attach_attached_form';
- // This form input (id = edit-attachlist) will hold the comma-separated ordered list of attached fids
+ // This form input (id = edit-attachlist) will hold the comma-separated
+ // ordered list of attached fids. We need to store the attachments (which
+ // might not yet been saved to the database) in two cases:
+ // 1) A form_validate fails when trying to save/preview. The form is not
+ // rebuild by form_alter, but form values are refilled. #value => '' would
+ // delete the attachlist collected so far, so use #default_value => '' instead.
$form['new']['attachlist'] = array(
'#type' => 'hidden',
- '#value' => '');
+ '#default_value' => '',
+ );
+ // 2) If form_validate didn't fail, the form is rebuild with form_alter
+ // and the value is reset. But we have the list in the POST parameters.
+ // Use default_value here, too, so that it can still be changed if we get
+ // a form_validate error *after* a successful preview.
+ if ($_POST['attachlist']) {
+ $form['new']['attachlist']['#default_value'] = $_POST['attachlist'];
+ }
return $form;
}
@@ -974,14 +1187,14 @@
$trees[$key] = webfm_tree($root_dir, $current);
}
} else {
- $err .= t('root directory not set for @role role ', array('@role' => $webfm_access_roles[$key]));
+ $err .= t('root directory not set for @role ', array('@role' => $webfm_access_roles[$key]));
}
}
} else {
$err = t('no root directory set in WebFM settings for this role');
}
}
-
+
if(count($trees)) {
webfm_json(array('status' => TRUE, 'tree' => $trees, 'current' => $webfm_root_path, 'admin' => $webfm_perm == WEBFM_ADMIN, 'err' => $err));
} else {
@@ -1005,6 +1218,14 @@
(array_key_exists($root_role, $webfm_roots))) {
$current = "/".$root;
}
+ else if(($root = variable_get('webfm_user_dir', '')) &&
+ (array_key_exists($root_role, $webfm_roots))) {
+ // User dir can be tokenized
+ if (function_exists('token_replace')) {
+ $root = token_replace($root, 'user', $user);
+ }
+ $current = "/".$root;
+ }
}
if(!isset($current)) {
webfm_json(array('status' => FALSE, 'data' => 'unknown tree'));
@@ -1019,6 +1240,7 @@
$tree = webfm_tree($root_dir, $current);
webfm_json(array('status' => isset($tree) ? TRUE : FALSE, 'tree' => $tree, 'current' => $current, 'admin' => $webfm_perm == WEBFM_ADMIN));
}
+
exit();
break;
@@ -1031,7 +1253,7 @@
webfm_json(array('status' => FALSE, 'data' => 'illegal read dir'));
exit();
}
-
+
// Test access rights
$perm_flag = FALSE;
if($webfm_perm == WEBFM_ADMIN) {
@@ -1042,6 +1264,7 @@
} else {
// If WEBFM_USER, test that read path is inside a legit root dir
$webfm_roots = webfm_get_root_dirs();
+
foreach($webfm_roots as $key => $sub_root) {
// The read path must be contained within a legitimate role root dir for this user
if($sub_root && webfm_check_path($param0, $sub_root)) {
@@ -1084,7 +1307,7 @@
if(is_dir($source)) {
//Only admins can delete directories (and contained files)
- if($webfm_perm == WEBFM_ADMIN) {
+ if($webfm_perm == WEBFM_ADMIN || webfm_path_access($source)) {
$err_arr[] = array();
$ret = webfm_delete_dir_recur($source, TRUE, $err_arr);
webfm_json(array('status' => $ret, 'data' => $err_arr));
@@ -1133,7 +1356,7 @@
//Create new directory
case "mkdir":
//Only admins can create directories
- if($webfm_perm == WEBFM_ADMIN) {
+ //if($webfm_perm == WEBFM_ADMIN) {
if(isset($_POST["param0"])) {
$source = $root_dir.trim(rawurldecode($_POST["param0"]));
$dest = t("New_Folder");
@@ -1142,14 +1365,14 @@
// exixts in current folder
$ret = webfm_mkdir($source, $dest, TRUE, $err_arr);
webfm_json(array('status' => $ret, 'data' => $err_arr));
- // if($ret)
+ // if($ret){
// unset($_SESSION['tree_'.$webfm_root_path]);
} else {
webfm_json(array('status' => FALSE, 'data' => 'insufficient params'));
}
- } else {
- webfm_json(array('status' => FALSE, 'data' => 'permission denied'));
- }
+ //} else {
+ // webfm_json(array('status' => FALSE, 'data' => 'permission denied'));
+ //}
exit();
break;
@@ -1158,7 +1381,7 @@
if(isset($_POST["param0"]) && isset($_POST["param1"])) {
$source = $root_dir.trim(rawurldecode($_POST["param0"]));
$dest = $root_dir.trim(rawurldecode($_POST["param1"]));
- if(is_dir($source) && ($webfm_perm != WEBFM_ADMIN)) {
+ if(is_dir($source) && !webfm_path_access($source)) {
//Only admins can manipulate directories
webfm_json(array('status' => FALSE, 'data' => 'permission denied'));
exit();
@@ -1191,7 +1414,8 @@
if(!ereg('\.\.', $dest)) {
$err_arr[] = array();
//rename permissions inside webfm_rename
- $ret = webfm_rename($source, $dest, ($webfm_perm == WEBFM_USER) ? $user->uid : 1, $err_arr);
+ //$ret = webfm_rename($source, $dest, ($webfm_perm == WEBFM_USER) ? $user->uid : 1, $err_arr);
+ $ret = webfm_rename($source, $dest, $user->uid, $err_arr);
webfm_json(array('status' => $ret, 'data' => $err_arr));
} else {
webfm_json(array('status' => FALSE, 'data' => 'illegal name'));
@@ -1350,14 +1574,43 @@
case "attach":
global $node;
if(isset($_POST["param0"])) {
+ // If $_POST["param1"] is set, we are in a preview or validation failure
+ // and have fids stored in the edit-attachments form, those that we fetched
+ // from the database before and those which are not yet attached (during
+ // a preview). Those fids are transfered through param1.
+ if (isset($_POST["param1"])) {
+ $fids = trim(strtolower(rawurldecode($_POST["param1"])));
+ webfm_json(array('status' => TRUE, 'data' => webfm_get_temp_attachments($fids), 'admin' => 'attach'));
+ exit();
+ break;
+ }
+ // Here we are in the edit form for the first time.
+ // For comments, the URL is "comment/edit/$cid" instead of node/$nid/edit.
+ // Unify those. We must distinguish between new and existing nodes/comments,
+ // because for new nodes webfm passed a string instead of a nid which was
+ // interpreted as nid=0. But now with comments, we *have* entries with nid=0
+ // in the table, so avoid fetching those.
+ // For new nodes and comments we can't get attachments from the database.
$node_str = trim(strtolower(rawurldecode($_POST["param0"])));
- // the 'node' var passed via AJAX is the action attribute of id=node-form
- if (($node_num = strstr($node_str, 'node/')) !== FALSE) {
- $node_arr = explode("/", $node_num);
- //'admin' is true (allow drag&drop) since only owners of a node can edit it
- webfm_json(array('status' => TRUE, 'data' => webfm_get_attachments($node_arr[1]), 'admin' => 'attach'));
- } else {
- webfm_json(array('status' => FALSE, 'data' => 'illegal path'));
+ // We edit an existing node: Fetch from database.
+ if (strpos($node_str, '/edit')) {
+ $node_str = str_replace('/edit', '', $node_str);
+ $selector = 'nid';
+ // The 'node' var passed via AJAX is the action attribute of id=node-form.
+ if (($node_num = strstr($node_str, 'node/')) == FALSE) {
+ $node_num = strstr($node_str, 'comment/');
+ $selector = 'cid';
+ }
+ if ($node_num) {
+ $node_arr = explode("/", $node_num);
+ // 'admin' is true (allow drag&drop) since only owners of a node can edit it.
+ webfm_json(array('status' => TRUE, 'data' => webfm_get_attachments($node_arr[1], $selector), 'admin' => 'attach'));
+ }
+ else {
+ webfm_json(array('status' => FALSE, 'data' => 'illegal path'));
+ exit();
+ break;
+ }
}
} else {
webfm_json(array('status' => FALSE, 'data' => 'insufficient params'));
@@ -1478,6 +1731,66 @@
exit();
break;
+///////////////////////////////////////////////////////////////////////////////
+
+ case "unzip":
+ if(isset($_POST["param0"])) {
+ $fid = rawurldecode($_POST["param0"]);
+ if(($file = webfm_get_file_record($fid)) !== FALSE) {
+ if($webfm_perm == WEBFM_ADMIN ||
+ $user->uid == $file->uid ||
+ webfm_file_mod_access($file)) {
+
+ $zip = new ZipArchive;
+ $dir = dirname($file->fpath);
+
+ // Extract files...
+ if ($zip->open($file->fpath) === TRUE) {
+ $zip->extractTo($dir);
+ $zip->close();
+
+ // now add files to database...
+ $zip = zip_open($file->fpath);
+ if ($zip) {
+ while ($zip_entry = zip_read($zip)) {
+ $filename = basename(zip_entry_name($zip_entry));
+ if(!webfm_insert_file($dir . '/' . $filename, $error)) {
+ webfm_json(array('status' => FALSE, 'data' => $error));
+ }
+ }
+ zip_close($zip);
+ }
+
+ /*
+ // and delete archive
+ $error = "";
+ $ret = TRUE;
+ if(@unlink($source)) {
+ if($file && !webfm_dbdelete_file($file->fid)) {
+ webfm_json(array('status' => $ret, 'data' => 'webfm_dbdelete_file() fail for '.$source));
+ }
+ } else if(file_exists($source)) {
+ webfm_json(array('status' => $ret, 'data' => $source.' could not be deleted'));
+ }
+ */
+ webfm_json(array('status' => TRUE, 'data' => 'unzip success'));
+ } else {
+ webfm_json(array('status' => FALSE, 'data' => 'unzip failed'));
+ }
+ } else {
+ webfm_json(array('status' => FALSE, 'data' => 'permission denied'));
+ }
+ } else {
+ webfm_json(array('status' => FALSE, 'data' => 'file record not found'));
+ }
+ } else {
+ webfm_json(array('status' => FALSE, 'data' => 'insufficient params'));
+ }
+ exit();
+ break;
+
+///////////////////////////////////////////////////////////////////////////////
+
default:
webfm_json(array('status' => FALSE, 'data' => 'illegal operation'));
exit();
@@ -1836,8 +2149,24 @@
$webfm_roots[1] = "/".$path;
}
}
+
+ // User directory
+ $path = variable_get('webfm_user_dir', '');
+ // Allow tokenized paths.
+ if (function_exists('token_replace')) {
+ $path = token_replace($path, 'user', $user);
+ }
+ if(!empty($path)) {
+ // Prevent redundant trees for user directory common with a role root dir
+ if(!in_array($path, $webfm_roots)) {
+ $webfm_roots[$user->name] = "/".$path;
+ // Create directory if neccesarry
+ $userdir = file_directory_path() . '/' . variable_get('webfm_root_dir', '') . '/' . $path;
+ file_check_directory($userdir, FILE_CREATE_DIRECTORY);
+ }
+ }
}
-
+
return $webfm_roots;
}
@@ -2073,9 +2402,16 @@
return isset($tree)?$tree:'';
}
-function webfm_get_attachments($nid) {
+function webfm_get_attachments($nid, $selector = 'nid') {
+ // If anything but a existing nid/cid is passed, it is equivalent to 0. This
+ // happened in webfm_ajax in the past. Although we fixed it there, make sure
+ // that we never run into this, because now there are entries with nid/cid=0.
+ if ($nid == 0) {
+ return array();
+ }
+
$files = array();
- $file_result = db_query('SELECT * FROM {webfm_file} f INNER JOIN {webfm_attach} a ON f.fid = a.fid WHERE a.nid = %d ORDER BY a.weight', $nid);
+ $file_result = db_query("SELECT * FROM {webfm_file} f INNER JOIN {webfm_attach} a ON f.fid = a.fid WHERE a.%s = %d ORDER BY a.weight", $selector, $nid);
while($file_record = db_fetch_object($file_result)) {
$_file = new webfm_fdesc($file_record);
if($_file->result == TRUE) {
@@ -2086,6 +2422,26 @@
}
/**
+ * Return file descriptors for an attachment that have not yet been saved.
+ * This happens on previewing posts.
+ *
+ * @param array $fids - a comma separated list of fids.
+ * @return array of file descriptors.
+ */
+function webfm_get_temp_attachments($fids) {
+ $files = array();
+ $fids_arr = split(',', $fids);
+ $file_result = db_query('SELECT * FROM {webfm_file} WHERE fid in ('. db_placeholders($fids_arr) .')', $fids_arr);
+ while ($file_record = db_fetch_object($file_result)) {
+ $_file = new webfm_fdesc($file_record);
+ if ($_file->result == TRUE) {
+ $files[] = $_file;
+ }
+ }
+ return $files;
+}
+
+/**
* File description class
*/
class webfm_fdesc {
@@ -2269,16 +2625,24 @@
}
// Files that have been attached are alway considered public to whoever can
- // access that node (nodeaccess security)
+ // access that node/comment (nodeaccess/commentaccess security).
if($match == FALSE && $webfm_perm != WEBFM_ADMIN) {
if($f->perm & WEBFM_FILE_ACCESS_PUBLIC_VIEW) {
$match = TRUE;
} else if($webfm_perm == WEBFM_USER || $webfm_perm == WEBFM_ATTACH_VIEW){
- //Check if the file is attached to a node
- $query = 'SELECT nid FROM {webfm_attach} WHERE fid = %d';
+ //Check if the file is attached to a node or comment.
+ $query = 'SELECT nid,cid FROM {webfm_attach} WHERE fid = %d';
$result = db_query($query, $f->fid);
if($result !== FALSE) {
while ($dbfid = db_fetch_array($result)) {
+ if ($dbfid['cid'] != 0 ) {
+ // For a comment, a user must be able to view the parent node and have "access_comments".
+ if (!user_access('access comments')) {
+ continue;
+ }
+ $comment = _comment_load($dbfid['cid']);
+ $dbfid['nid'] = $comment->nid;
+ }
$node = node_load($dbfid['nid']);
if (node_access('view', $node)) {
$match = TRUE;
@@ -2482,7 +2846,12 @@
if(!$role_ext_regex[$rid]) {
$extensions = variable_get("webfm_extensions_".$rid, '');
- $role_ext_regex[$rid] = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
+ if ($extensions == '*') {
+ $role_ext_regex[$rid] = '//';
+ }
+ else {
+ $role_ext_regex[$rid] = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
+ }
}
return $role_ext_regex[$rid];
@@ -2735,16 +3104,26 @@
*
* @param int $nid
* @param array $fids - could be a comma seperated string - we need to work that out - works both ways now
+ * @param int $cid - Optional, comment id.
* @return TRUE if records were updated - NULL if no changes were required.
*/
-function webfm_dbupdate_attach($nid, $fids){
+function webfm_dbupdate_attach($nid, $fids, $cid = 0){
+ if ($cid == 0 ) {
+ $id = $nid;
+ $selector = 'nid';
+ }
+ else {
+ $id = $cid;
+ $selector = 'cid';
+ }
+
$i = 0;
- if(!webfm_check_attach_order($nid, $fids)){ //the new fids are different from the old ones
- $query = "DELETE FROM {webfm_attach} WHERE nid = %d";
- if($result = db_query($query, $nid)){
+ if (!webfm_check_attach_order($nid, $fids, $cid)) { //the new fids are different from the old ones
+ $query = "DELETE FROM {webfm_attach} WHERE %s = %d";
+ if ($result = db_query($query, $selector, $id)) {
foreach($fids as $fid){
if($fid)
- webfm_dbinsert_attach($nid, $fid, $i++);
+ webfm_dbinsert_attach($nid, $fid, $i++, $cid);
$flag = TRUE;
}
if($flag === TRUE) return TRUE;
@@ -2757,12 +3136,21 @@
*
* @param int $nid - node id
* @param array $fids - array of file ids
+ * @param int $cid - Optional, comment id.
* @return bool - TRUE if the attach order is the same - FALSE if it has changed
*/
-function webfm_check_attach_order($nid, $fids){
+function webfm_check_attach_order($nid, $fids, $cid = 0) {
+ if ($cid == 0 ) {
+ $id = $nid;
+ $selector = 'nid';
+ }
+ else {
+ $id = $cid;
+ $selector = 'cid';
+ }
//check array against db result
- $query = "SELECT fid FROM {webfm_attach} WHERE nid = %d ORDER BY weight";
- $result = db_query($query, $nid);
+ $query = "SELECT fid FROM {webfm_attach} WHERE %s = %d ORDER BY weight";
+ $result = db_query($query, $selector, $id);
$match = TRUE;
$i = 0;
@@ -2785,23 +3173,35 @@
* @param int $nid - node id
* @param int $fid - file id from the webfm_file table
* @param int $weight - weight value
- *
- * @return bool - TRUE if success - else FALSE
- */
-function webfm_dbinsert_attach($nid, $fid, $weight){
- $query = 'SELECT * FROM {webfm_attach} WHERE nid = %d AND fid = %d';
- $result = db_query($query, $nid, $fid);
+ * @param int $cid - Optional, comment id. If given, $nid is set to 0 because
+ * an attachment is stored either for a node OR a comment.
+ * @return bool - TRUE if success - else FALSE
+ */
+function webfm_dbinsert_attach($nid, $fid, $weight, $cid = 0) {
+ if ($cid == 0 ) {
+ $selector = 'nid';
+ $type = 'node';
+ $id = $nid;
+ }
+ else {
+ $selector = 'cid';
+ $type = 'comment';
+ $id = $cid;
+ $nid = 0;
+ }
+ $query = "SELECT * FROM {webfm_attach} WHERE %s = %d AND fid = %d";
+ $result = db_query($query, $selector, $id, $fid);
$exist = FALSE;
while ($exist = db_fetch_object($result)){
- drupal_set_message(t('File is already attached to this node.'));
+ drupal_set_message(t('File is already attached to this %t.', array('%t' => $type)));
return FALSE;
}
if ($exist === FALSE) {
//actually do the attachment if its not already attached....
- $query = 'INSERT INTO {webfm_attach} (nid, fid, weight) VALUES (%d, %d, %d)';
- $result = db_query($query, $nid, $fid, $weight);
+ $query = 'INSERT INTO {webfm_attach} (nid, fid, weight, cid) VALUES (%d, %d, %d, %d)';
+ $result = db_query($query, $nid, $fid, $weight, $cid);
if($result === FALSE) {
- drupal_set_message(t('Query Failed: Could not attach files to node ') . $nid);
+ drupal_set_message(t('Query Failed: Could not attach files to %t %n', array('%t' => $type, '%n' => $id)));
return FALSE;
} else {
return TRUE;
@@ -2810,6 +3210,26 @@
}
/**
+ * webfm_dbdelete_attachments - deletes nodes/comments file associations.
+ *
+ * @param int $id - Node or comment id.
+ * @param selector - Tell if we handle a node or a comment.
+ * @return bool - TRUE if success - else FALSE
+ *
+ */
+function webfm_dbdelete_attachments($id, $selector = 'nid') {
+ $type = ($selector == 'nid') ? 'node' : 'comment';
+ $query = "DELETE FROM {webfm_attach} WHERE %s = %d";
+ $result = db_query($query, $selector, $id);
+ if($result === FALSE) {
+ drupal_set_message(t('Failed to remove file attachments for deleted %type %id',
+ array('%type' => $type, '%id' => $id)));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
* webfm_dbdelete_attach - deletes node file associations given a nid and fid
*
* @param int $nid - node id
diff -ru webfm-6.x-2.9-alpha2/webfm_file.inc webfm/webfm_file.inc
--- webfm-6.x-2.9-alpha2/webfm_file.inc 2008-04-08 08:28:14.000000000 +0200
+++ webfm/webfm_file.inc 2008-08-15 17:25:00.000000000 +0200
@@ -89,8 +89,8 @@
}
//Directory
- //if target is a directory, new name is a unique path and we are an admin...
- else if(is_dir($source) && !is_dir($dest) && ($uid == 1)) {
+ //if target is a directory, new name is a unique path and we have access to that dir...
+ else if(is_dir($source) && !is_dir($dest) && webfm_path_access($source)) {
//if the target isn't read-only
if(rename($source, $dest_temp)) {
//directory rename is OK, back out, rename db files and rename dir again
@@ -204,7 +204,7 @@
*
*/
function webfm_move($source, $dest, $uid, &$err_arr) {
- if(is_dir($source) && $uid == 1) {
+ if(is_dir($source) && webfm_path_access($source)) {
return webfm_move_dir_recur($source, $dest, $uid, FALSE, $err_arr);
} elseif(is_file($source)) {
$dest .= '/' . strrev(substr(strrev($source), 0, strpos(strrev($source), '/')));