* Add action to share filemanager folder (readonly) with hidden upload folder

This commit is contained in:
nathangray 2020-03-24 20:34:04 -06:00
parent 6aec7858cc
commit 7163acfe1d
16 changed files with 356 additions and 118 deletions

View File

@ -478,8 +478,11 @@ var et2_file = /** @class */ (function (_super) {
var event = jQuery.Event('upload');
event.data = this;
// Callback
if (this.options.onFinishOne) {
return et2_call(this.options.onFinishOne, event, response, name);
if (typeof this.onFinishOne == 'function') {
this.onFinishOne(event, response, name);
}
else if (this.options.onFinishOne) {
et2_call(this.options.onFinishOne, event, response, name);
}
return true;
};
@ -596,7 +599,7 @@ var et2_file = /** @class */ (function (_super) {
},
onFinishOne: {
"name": "Finish event handler for each one",
"type": "any",
"type": "js",
"default": et2_no_init,
"description": "A (js) function called when a file to be uploaded is finished."
},

View File

@ -89,7 +89,7 @@ export class et2_file extends et2_inputWidget
},
onFinishOne: {
"name": "Finish event handler for each one",
"type": "any",
"type": "js",
"default": et2_no_init,
"description": "A (js) function called when a file to be uploaded is finished."
},
@ -665,9 +665,13 @@ export class et2_file extends et2_inputWidget
event.data = this;
// Callback
if(this.options.onFinishOne)
if(typeof this.onFinishOne == 'function')
{
return et2_call(this.options.onFinishOne,event,response,name);
this.onFinishOne(event, response, name);
}
else if (this.options.onFinishOne)
{
et2_call(this.options.onFinishOne,event,response,name);
}
return true;
}

View File

@ -1587,9 +1587,10 @@ var EgwApp = /** @class */ (function () {
* @param {Boolean} _writable Allow edit access from the share.
* @param {Boolean} _files Allow access to files from the share.
* @param {Function} _callback Callback with results
* @param {Object} _extra Additional (app-specific or special) parameters
* @returns {Boolean} returns false if not successful
*/
EgwApp.prototype.share_link = function (_action, _senders, _target, _writable, _files, _callback) {
EgwApp.prototype.share_link = function (_action, _senders, _target, _writable, _files, _callback, _extra) {
var path = _senders[0].id;
if (!path) {
return this.egw.message(this.egw.lang('Missing share path. Unable to create share.'), 'error');
@ -1606,7 +1607,7 @@ var EgwApp = /** @class */ (function () {
if (typeof _files === 'undefined' && _action.parent && _action.parent.getActionById('shareFiles')) {
_files = _action.parent.getActionById('shareFiles').checked || false;
}
return egw.json('EGroupware\\Api\\Sharing::ajax_create', [_action.id, path, _writable, _files], _callback ? _callback : this._share_link_callback, this, true, this).sendRequest();
return egw.json('EGroupware\\Api\\Sharing::ajax_create', [_action.id, path, _writable, _files, _extra], _callback ? _callback : this._share_link_callback, this, true, this).sendRequest();
};
EgwApp.prototype.share_merge = function (_action, _senders, _target) {
var parent = _action.parent.parent;

View File

@ -1987,9 +1987,10 @@ export abstract class EgwApp
* @param {Boolean} _writable Allow edit access from the share.
* @param {Boolean} _files Allow access to files from the share.
* @param {Function} _callback Callback with results
* @param {Object} _extra Additional (app-specific or special) parameters
* @returns {Boolean} returns false if not successful
*/
share_link(_action, _senders, _target, _writable?, _files?, _callback?){
share_link(_action, _senders, _target, _writable?, _files?, _callback?, _extra?){
var path = _senders[0].id;
if(!path)
{
@ -2011,7 +2012,7 @@ export abstract class EgwApp
_files = _action.parent.getActionById('shareFiles').checked || false;
}
return egw.json('EGroupware\\Api\\Sharing::ajax_create', [_action.id, path, _writable, _files],
return egw.json('EGroupware\\Api\\Sharing::ajax_create', [_action.id, path, _writable, _files, _extra],
_callback ? _callback : this._share_link_callback, this, true, this).sendRequest();
}

View File

@ -114,10 +114,7 @@ class Photo
$path = $tmp;
}
return Api\Vfs\Sharing::share2link(Api\Vfs\Sharing::create(
$path,
Api\Vfs\Sharing::READONLY,
basename($path),
array()
'', $path, Api\Vfs\Sharing::READONLY, basename($path), array()
));
}
}

View File

@ -552,17 +552,18 @@ class Sharing
/**
* Create a new share
*
* @param string $action_id Specific type of share being created, default ''
* @param string $path either path in temp_dir or vfs with optional vfs scheme
* @param string $mode self::LINK: copy file in users tmp-dir or self::READABLE share given vfs file,
* if no vfs behave as self::LINK
* if no vfs behave as self::LINK
* @param string $name filename to use for $mode==self::LINK, default basename of $path
* @param string|array $recipients one or more recipient email addresses
* @param array $extra =array() extra data to store
* @return array with share data, eg. value for key 'share_token'
* @throw Api\Exception\NotFound if $path not found
* @throw Api\Exception\AssertionFailed if user temp. directory does not exist and can not be created
* @return array with share data, eg. value for key 'share_token'
*/
public static function create($path, $mode, $name, $recipients, $extra=array())
public static function create(string $action_id, $path, $mode, $name, $recipients, $extra = array())
{
if (!isset(static::$db)) static::$db = $GLOBALS['egw']->db;
@ -646,8 +647,9 @@ class Sharing
*
* @param String $action
* @param String $path
* @param boolean $writable
* @param boolean $files
* @param boolean $writable Allow editing the shared entry / folder / file
* @param boolean $files For sharing an application entry, allow access to the linked files
* @param $extra Additional extra parameters
*/
public static function ajax_create($action, $path, $writable = false, $files = false, $extra = array())
{
@ -661,6 +663,7 @@ class Sharing
'include_files' => $files
);
$share = $class::create(
$action,
$path,
$writable ? Sharing::WRITABLE : Sharing::READONLY,
basename($path),

View File

@ -13,16 +13,15 @@
namespace EGroupware\Api\Storage;
use DOMDocument;
use EGroupware\Api;
use EGroupware\Stylite;
use DOMDocument;
use XSLTProcessor;
use tidy;
use uiaccountsel;
use XSLTProcessor;
use ZipArchive;
// explicit import old, non-namespaced phpgwapi classes
use uiaccountsel;
/**
* Document merge print
@ -519,7 +518,7 @@ abstract class Merge
//$extra['share_writable'] |= ($mode == Sharing::WRITABLE ? 1 : 0);
return \EGroupware\Stylite\Link\Sharing::create($path, $mode, NULL, $recipients, $extra);
return \EGroupware\Stylite\Link\Sharing::create('', $path, $mode, NULL, $recipients, $extra);
}
/**

View File

@ -44,6 +44,9 @@ class Sharing extends \EGroupware\Api\Sharing
const READONLY = 'share_ro';
const WRITABLE = 'share_rw';
const HIDDEN_UPLOAD = 9; // 8 is the next bitwise flag + 1 for writable
const HIDDEN_UPLOAD_DIR = '/Upload';
/**
* Modes for sharing files
*
@ -185,17 +188,18 @@ class Sharing extends \EGroupware\Api\Sharing
/**
* Create a new share
*
* @param string $action_id Name of the action used to create the share. Allows for customization.
* @param string $path either path in temp_dir or vfs with optional vfs scheme
* @param string $mode self::LINK: copy file in users tmp-dir or self::READABLE share given vfs file,
* if no vfs behave as self::LINK
* if no vfs behave as self::LINK
* @param string $name filename to use for $mode==self::LINK, default basename of $path
* @param string|array $recipients one or more recipient email addresses
* @param array $extra =array() extra data to store
* @return array with share data, eg. value for key 'share_token'
* @throw Api\Exception\NotFound if $path not found
* @throw Api\Exception\AssertionFailed if user temp. directory does not exist and can not be created
* @return array with share data, eg. value for key 'share_token'
*/
public static function create($path, $mode, $name, $recipients, $extra=array())
public static function create(string $action_id, $path, $mode, $name, $recipients, $extra = array())
{
if (!isset(self::$db)) self::$db = $GLOBALS['egw']->db;
@ -245,10 +249,17 @@ class Sharing extends \EGroupware\Api\Sharing
{
throw new Api\Exception\NotFound("'$path' NOT found!");
}
// Set up anonymous upload directory
if($action_id == 'shareUploadDir')
{
static::create_hidden_upload($path, $mode, $name, $recipients, $extra);
}
// check if file has been shared before, with identical attributes
if (($mode != self::LINK ))
{
return parent::create($vfs_path ? $vfs_path : $path, $mode, $name, $recipients, $extra);
return parent::create($action_id, $vfs_path ? $vfs_path : $path, $mode, $name, $recipients, $extra);
}
else
{
@ -286,10 +297,54 @@ class Sharing extends \EGroupware\Api\Sharing
$vfs_path = $tmp_file;
}
return parent::create($vfs_path, $mode, $name, $recipients, $extra);
return parent::create($action_id, $vfs_path, $mode, $name, $recipients, $extra);
}
}
/**
* Check the given path for an anonymous upload directory, and create it if it does not
* exist yet. Anon upload directory is not visible over the share, and any files uploaded
* to the share are placed inside it instead.
*
* @param $path
* @param $mode
* @param $name
* @param $recipients
* @param $extra
*
* @throws Api\Exception\AssertionFailed
* @throws Api\Exception\NoPermission
* @throws Api\Exception\WrongParameter
*/
protected static function create_hidden_upload($path, $mode, $name, $recipients, &$extra)
{
$upload_dir = Vfs::concat($path, self::HIDDEN_UPLOAD_DIR);
if(($stat = Vfs::stat($upload_dir)) && !Vfs::check_access($upload_dir, Vfs::WRITABLE, $stat))
{
throw new Api\Exception\NoPermission("Upload directory exists, but you have no write permission");
}
if (!($stat = Vfs::stat($upload_dir)))
{
// Directory is not there, create it
if (!mkdir($upload_dir))
{
throw new Api\Exception\NoPermission("Could not make upload directory");
}
}
// Set flags so things work
$extra['share_writable'] = self::HIDDEN_UPLOAD;
}
/**
* Does this share have a hidden upload directory
*/
public function has_hidden_upload()
{
return (int)$this->share['share_writable'] == self::HIDDEN_UPLOAD;
}
/**
* Delete specified shares and unlink temp. files
*
@ -364,6 +419,17 @@ class Sharing extends \EGroupware\Api\Sharing
$actions['share']['children']['shareReadonlyLink']['order'] = 22;
$actions['share']['children']['shareWritable']['group'] = 3;
// Add in a hidden upload directory
$actions['share']['children']['shareUploadDir'] = array(
'caption' => 'Hidden uploads',
'group' => 1,
'order' => 30,
'enabled' => 'javaScript:app.filemanager.hidden_upload_enabled',
'onExecute' => 'javaScript:app.filemanager.share_link',
'icon' => 'upload',
'hideOnDisabled' => true
);
// Add in merge to document
if (class_exists($appname.'_merge'))
{
@ -451,6 +517,43 @@ if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php'
class SharingUi extends filemanager_ui
{
/**
* Get active view - override so it points to this class
*
* @return string
*/
public static function get_view()
{
return array(new SharingUi(), 'listview');
}
/**
* Filemanager listview
*
* @param array $content
* @param string $msg
*/
function listview(array $content=null,$msg=null)
{
$this->etemplate = new Api\Etemplate(static::LIST_TEMPLATE);
// Override and take over get_rows so we can filter out upload directory, or other customisations
$content['nm']['get_rows'] = '.' . __CLASS__ . '.get_rows';
if (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload())
{
// No new anything
$this->etemplate->disableElement('nm[new]');
$this->etemplate->setElementAttribute('nm[button][createdir]', 'readonly', true);
// Take over upload, change target and conflict strategy
$path = Vfs::concat(static::get_home_dir(), Vfs\Sharing::HIDDEN_UPLOAD_DIR);
$this->etemplate->setElementAttribute('nm[upload]', 'onFinishOne', "app.filemanager.upload(ev, 1, '$path', 'rename')");
}
return parent::listview($content, $msg);
}
/**
* Get the configured start directory for the current user
*
@ -472,7 +575,7 @@ if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php'
$group = 1;
// do not add edit setting action when we are in sharing
unset($actions['edit']);
if(Vfs::is_writable($GLOBALS['egw']->sharing->get_root()))
if (Vfs::is_writable($GLOBALS['egw']->sharing->get_root()))
{
return $actions;
}
@ -501,9 +604,69 @@ if (file_exists(__DIR__.'/../../../filemanager/inc/class.filemanager_ui.inc.php'
$options = parent::get_vfs_options($query);
// Hide symlinks
$options['type'] = '!l';
// TODO: This hides everything, see Vfs::_check_add() line 648
//$options['type'] = '!l';
return $options;
}
protected function is_hidden_upload_dir($directory)
{
if (!isset($GLOBALS['egw']->sharing)) return false;
return Vfs::is_dir($directory) && $directory == Vfs::concat( $GLOBALS['egw']->sharing->get_root(), Vfs\Sharing::HIDDEN_UPLOAD_DIR );
}
/**
* Callback to fetch the rows for the nextmatch widget
*
* @param array $query
* @param array &$rows
* @return int
*/
function get_rows(&$query, &$rows)
{
$hidden_upload = (isset($GLOBALS['egw']->sharing) && $GLOBALS['egw']->sharing->has_hidden_upload());
// Check for navigating outside share, redirect back to share
if (!Vfs::stat($query['path'],false) || !Vfs::is_dir($query['path']) || !Vfs::check_access($query['path'],Vfs::READABLE) ||
// Not allowed in hidden upload dir
$hidden_upload && strpos($query['path'], Sharing::HIDDEN_UPLOAD_DIR) === 0)
{
// only redirect, if it would be to some other location, gives redirect-loop otherwise
if ($query['path'] != ($path = static::get_home_dir()))
{
// we will leave here, since we are not allowed, go back to root
// TODO: Give message about it, redirect to home dir
}
$rows = array();
return 0;
}
// Get file list from parent
$total = parent::get_rows($query, $rows);
if(! $hidden_upload )
{
return $total;
}
// tell client-side if directory is writeable or not
$response = Api\Json\Response::get();
$response->call('app.filemanager.set_readonly', $query['path'], true);
// Hide the hidden upload directory, mark everything else as readonly
foreach($rows as $key => &$row)
{
if($this->is_hidden_upload_dir($row['path']))
{
unset($rows[$key]);
$total--;
continue;
}
$row['class'] .= 'noEdit noDelete ';
}
return $total;
}
}
}

View File

@ -416,7 +416,7 @@ class SharingBase extends LoggedInTest
}
// Create share
$this->shares[] = $share = TestSharing::create($path, $mode, $name, $recipients, $extra);
$this->shares[] = $share = TestSharing::create('', $path, $mode, $name, $recipients, $extra);
return $share;
}

View File

@ -36,7 +36,7 @@ class SharingHooksTest extends SharingBase
Sharing::delete(array('share_path' => $test_file));
// Create share
$this->shares[] = $created_share = Sharing::create($test_file, Sharing::READONLY, '', '');
$this->shares[] = $created_share = Sharing::create('', $test_file, Sharing::READONLY, '', '');
$this->assertEquals(Vfs::PREFIX . $test_file, $created_share['share_path']);
@ -64,7 +64,7 @@ class SharingHooksTest extends SharingBase
Sharing::delete(array('share_path' => $test_file));
// Create share
$this->shares[] = $created_share = Sharing::create($test_file, Sharing::READONLY, '', '');
$this->shares[] = $created_share = Sharing::create('', $test_file, Sharing::READONLY, '', '');
$this->assertEquals(Vfs::PREFIX . $test_file, $created_share['share_path']);
@ -91,7 +91,7 @@ class SharingHooksTest extends SharingBase
Sharing::delete(array('share_path' => $test_file));
// Create share
$this->shares[] = $created_share = Sharing::create($test_file, Sharing::READONLY, '', '');
$this->shares[] = $created_share = Sharing::create('', $test_file, Sharing::READONLY, '', '');
$this->assertEquals(Vfs::PREFIX . $test_file, $created_share['share_path']);

View File

@ -20,7 +20,6 @@ namespace EGroupware\Api\Vfs;
require_once __DIR__ . '/SharingBase.php';
use EGroupware\Api\Vfs;
use EGroupware\Api\LoggedInTest as LoggedInTest;
class SharingTest extends SharingBase
@ -231,7 +230,7 @@ class SharingTest extends SharingBase
);
// Create share
$this->shares[] = $created_share = Sharing::create($symlink, Sharing::READONLY, '', '');
$this->shares[] = $created_share = Sharing::create('', $symlink, Sharing::READONLY, '', '');
$this->assertEquals($file, $created_share['share_path']);
}
@ -257,7 +256,7 @@ class SharingTest extends SharingBase
);
// Create share
$this->shares[] = $created_share = Sharing::create($symlink, Sharing::READONLY, '', '');
$this->shares[] = $created_share = Sharing::create('', $symlink, Sharing::READONLY, '', '');
$this->assertEquals($file, $created_share['share_path']);
}

View File

@ -249,7 +249,7 @@ class filemanager_merge extends Api\Storage\Merge
$recipients = array();
$extra = array();
return \EGroupware\Api\Vfs\Sharing::create($path, $mode, NULL, $recipients, $extra);
return \EGroupware\Api\Vfs\Sharing::create('', $path, $mode, NULL, $recipients, $extra);
}
/**

View File

@ -48,6 +48,8 @@ class filemanager_ui
*
*/
public static $merge_prop_namespace = '';
protected $etemplate;
const LIST_TEMPLATE = 'filemanager.index';
/**
* Constructor
@ -466,7 +468,7 @@ class filemanager_ui
*/
function listview(array $content=null,$msg=null)
{
$tpl = new Etemplate('filemanager.index');
$tpl = $this->etemplate ? $this->etemplate : new Etemplate(static::LIST_TEMPLATE);
if($msg) Framework::message($msg);
@ -569,7 +571,7 @@ class filemanager_ui
// sharing has no divAppbox, we need to set popupMainDiv instead, to be able to drop files everywhere
if (substr($_SERVER['SCRIPT_FILENAME'], -10) == '/share.php')
{
$tpl->setElementAttribute('nm[buttons][upload]', 'drop_target', 'popupMainDiv');
$tpl->setElementAttribute('nm[upload]', 'drop_target', 'popupMainDiv');
}
// Set view button to match current settings
if($content['nm']['view'] == 'tile')
@ -1483,82 +1485,20 @@ class filemanager_ui
switch($action)
{
case 'upload':
$script_error = 0;
foreach($selected as $tmp_name => &$data)
{
$path = Vfs::concat($dir, Vfs::encodePathComponent($data['name']));
if(Vfs::deny_script($path))
{
if (!isset($script_error))
{
$arr['msg'] .= ($arr['msg'] ? "\n" : '').lang('You are NOT allowed to upload a script!');
}
++$script_error;
++$arr['errs'];
unset($selected[$tmp_name]);
}
elseif (Vfs::is_dir($path))
{
$data['confirm'] = 'is_dir';
}
elseif (!$data['confirmed'] && Vfs::stat($path))
{
$data['confirm'] = true;
}
else
{
if (is_dir($GLOBALS['egw_info']['server']['temp_dir']) && is_writable($GLOBALS['egw_info']['server']['temp_dir']))
{
$tmp_path = $GLOBALS['egw_info']['server']['temp_dir'] . '/' . basename($tmp_name);
}
else
{
$tmp_path = ini_get('upload_tmp_dir').'/'.basename($tmp_name);
}
if (Vfs::copy_uploaded($tmp_path, $path, $props, false))
{
++$arr['files'];
$uploaded[] = $data['name'];
}
else
{
++$arr['errs'];
}
}
}
if ($arr['errs'] > $script_error)
{
$arr['msg'] .= ($arr['msg'] ? "\n" : '').lang('Error uploading file!');
}
if ($arr['files'])
{
$arr['msg'] .= ($arr['msg'] ? "\n" : '').lang('%1 successful uploaded.', implode(', ', $uploaded));
}
$arr['uploaded'] = $selected;
$arr['path'] = $dir;
$arr['props'] = $props;
static::handle_upload_action($action, $selected, $dir, $props, $arr);
break;
case 'shareWritableLink':
case 'shareReadonlyLink':
if ($action === 'shareWritableLink')
{
$share = Vfs\Sharing::create(
$selected,
Vfs\Sharing::WRITABLE,
basename($selected),
array(),
array('share_writable' => true)
'', $selected, Vfs\Sharing::WRITABLE, basename($selected), array(), array('share_writable' => true)
);
}
else
{
$share = Vfs\Sharing::create(
$selected,
Vfs\Sharing::READONLY,
basename($selected),
array()
'', $selected, Vfs\Sharing::READONLY, basename($selected), array()
);
}
$arr["share_link"] = $link = Vfs\Sharing::share2link($share);
@ -1592,6 +1532,102 @@ class filemanager_ui
return $arr;
}
/**
* Deal with an uploaded file
*
* @param string $action Should be 'upload'
* @param $selected Array of file information
* @param string $dir Target directory
* @param $props
* @param string[] $arr Result
*
* @throws Api\Exception\AssertionFailed
*/
protected static function handle_upload_action(string $action, $selected, $dir, $props, &$arr)
{
$script_error = 0;
$conflict = $selected['conflict'];
unset($selected['conflict']);
foreach($selected as $tmp_name => &$data)
{
$path = Vfs::concat($dir, Vfs::encodePathComponent($data['name']));
if(Vfs::deny_script($path))
{
if (!isset($script_error))
{
$arr['msg'] .= ($arr['msg'] ? "\n" : '').lang('You are NOT allowed to upload a script!');
}
++$script_error;
++$arr['errs'];
unset($selected[$tmp_name]);
continue;
}
elseif (Vfs::is_dir($path))
{
$data['confirm'] = 'is_dir';
continue;
}
elseif (!$data['confirmed'] && Vfs::stat($path))
{
// File exists, what to do?
switch($conflict)
{
case 'overwrite':
unset($data['confirm']);
$data['confirmed'] = true;
break;
case 'rename':
// Find a unique name
$i = 1;
$info = pathinfo($path);
while(Vfs::file_exists($path))
{
$path = $info['dirname'] . '/'. $info['filename'] . " ($i)." . $info['extension'];
$i++;
}
break;
case 'ask':
default:
$data['confirm'] = true;
}
}
if(!$data['confirm'])
{
if (is_dir($GLOBALS['egw_info']['server']['temp_dir']) && is_writable($GLOBALS['egw_info']['server']['temp_dir']))
{
$tmp_path = $GLOBALS['egw_info']['server']['temp_dir'] . '/' . basename($tmp_name);
}
else
{
$tmp_path = ini_get('upload_tmp_dir') . '/' . basename($tmp_name);
}
if (Vfs::copy_uploaded($tmp_path, $path, $props, false))
{
++$arr['files'];
$uploaded[] = $data['name'];
}
else
{
++$arr['errs'];
}
}
}
if ($arr['errs'] > $script_error)
{
$arr['msg'] .= ($arr['msg'] ? "\n" : '').lang('Error uploading file!');
}
if ($arr['files'])
{
$arr['msg'] .= ($arr['msg'] ? "\n" : '').lang('%1 successful uploaded.', implode(', ', $uploaded));
}
$arr['uploaded'] = $selected;
$arr['path'] = $dir;
$arr['props'] = $props;
}
/**
* Convert perms array back to integer mode
*

View File

@ -254,14 +254,18 @@ var filemanagerAPP = /** @class */ (function (_super) {
* @param {event} _event
* @param {number} _file_count
* @param {string=} _path where the file is uploaded to, default current directory
* @param {string} _conflict What to do if the file conflicts with one on the server
*/
filemanagerAPP.prototype.upload = function (_event, _file_count, _path) {
filemanagerAPP.prototype.upload = function (_event, _file_count, _path, _conflict) {
if (_conflict === void 0) { _conflict = "ask"; }
if (typeof _path == 'undefined') {
_path = this.get_path();
}
if (_file_count && !jQuery.isEmptyObject(_event.data.getValue())) {
var widget = _event.data;
egw.json('filemanager_ui::ajax_action', ['upload', widget.getValue(), _path], this._upload_callback, this, true, this).sendRequest();
var value = widget.getValue();
value.conflict = _conflict;
egw.json('filemanager_ui::ajax_action', ['upload', value, _path, _conflict], this._upload_callback, this, true, this).sendRequest();
widget.set_value('');
}
};
@ -974,7 +978,8 @@ var filemanagerAPP = /** @class */ (function (_super) {
if (!path) {
_senders[0] = { id: this.get_path() };
}
_super.prototype.share_link.call(this, _action, _senders, _target, _writable, _files, _callback);
var _extra = {};
_super.prototype.share_link.call(this, _action, _senders, _target, _writable, _files, _callback, _extra);
};
/**
* Share-link callback
@ -1011,6 +1016,16 @@ var filemanagerAPP = /** @class */ (function (_super) {
value: { content: { "share_link": _data.share_link } }
});
};
/**
* Check if a row can have the Hidden Uploads action
* Needs to be a directory
*/
filemanagerAPP.prototype.hidden_upload_enabled = function (_action, _senders) {
var data = egw.dataGetUIDdata(_senders[0].id);
var readonly = (data.data.class || '').split(/ +/).indexOf('noEdit') >= 0;
// symlinks dont have mime 'http/unix-directory', but server marks all directories with class 'isDir'
return (data.data.is_dir && !readonly);
};
/**
* View the link from an existing share
* (EPL only)

View File

@ -290,8 +290,9 @@ export class filemanagerAPP extends EgwApp
* @param {event} _event
* @param {number} _file_count
* @param {string=} _path where the file is uploaded to, default current directory
* @param {string} _conflict What to do if the file conflicts with one on the server
*/
upload(_event, _file_count : number, _path? : string)
upload(_event, _file_count : number, _path? : string, _conflict = "ask")
{
if(typeof _path == 'undefined')
{
@ -300,7 +301,9 @@ export class filemanagerAPP extends EgwApp
if (_file_count && !jQuery.isEmptyObject(_event.data.getValue()))
{
let widget = _event.data;
egw.json('filemanager_ui::ajax_action', ['upload', widget.getValue(), _path],
let value = widget.getValue();
value.conflict = _conflict;
egw.json('filemanager_ui::ajax_action', ['upload', value, _path, _conflict],
this._upload_callback, this, true, this
).sendRequest();
widget.set_value('');
@ -1179,7 +1182,8 @@ export class filemanagerAPP extends EgwApp
{
_senders[0] = {id: this.get_path()};
}
super.share_link(_action, _senders, _target, _writable, _files, _callback);
let _extra = {};
super.share_link(_action, _senders, _target, _writable, _files, _callback, _extra);
}
/**
@ -1223,6 +1227,19 @@ export class filemanagerAPP extends EgwApp
});
}
/**
* Check if a row can have the Hidden Uploads action
* Needs to be a directory
*/
hidden_upload_enabled(_action: egwAction, _senders: egwActionObject[])
{
let data = egw.dataGetUIDdata(_senders[0].id);
let readonly = (data.data.class || '').split(/ +/).indexOf('noEdit') >= 0;
// symlinks dont have mime 'http/unix-directory', but server marks all directories with class 'isDir'
return (data.data.is_dir && !readonly);
}
/**
* View the link from an existing share
* (EPL only)

View File

@ -11,13 +11,13 @@
*/
use EGroupware\Api;
use EGroupware\Api\Link;
use EGroupware\Api\Framework;
use EGroupware\Api\Egw;
use EGroupware\Api\Acl;
use EGroupware\Api\Egw;
use EGroupware\Api\Etemplate;
use EGroupware\Api\Vfs;
use EGroupware\Api\Framework;
use EGroupware\Api\Link;
use EGroupware\Api\Mail;
use EGroupware\Api\Vfs;
/**
* Mail interface class for compose mails in popup
@ -2664,11 +2664,11 @@ class mail_compose
// create share
if ($filemode == Vfs\Sharing::WRITABLE || $expiration || $password)
{
$share = stylite_sharing::create($path, $filemode, $attachment['name'], $recipients, $expiration, $password);
$share = stylite_sharing::create('', $path, $filemode, $attachment['name'], $recipients, $expiration, $password);
}
else
{
$share = Vfs\Sharing::create($path, $filemode, $attachment['name'], $recipients);
$share = Vfs\Sharing::create('', $path, $filemode, $attachment['name'], $recipients);
}
$link = Vfs\Sharing::share2link($share);