mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-23 23:29:20 +01:00
* Add action to share filemanager folder (readonly) with hidden upload folder
This commit is contained in:
parent
6aec7858cc
commit
7163acfe1d
@ -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."
|
||||
},
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
));
|
||||
}
|
||||
}
|
@ -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),
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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']);
|
||||
|
||||
|
@ -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']);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user