Change merge download/Collabora to a common generation method, avoiding need to POST.

This allows Kanban to download merge files
This commit is contained in:
nathangray 2021-06-23 11:19:36 -06:00 committed by nathan
parent 0a51e80639
commit a728276a15
4 changed files with 203 additions and 30 deletions

View File

@ -3,8 +3,9 @@
* *
* @link: https://www.egroupware.org * @link: https://www.egroupware.org
* @package addressbook * @package addressbook
* @author Hadi Nategh <hn-AT-stylite.de> * @author Hadi Nategh <hn-AT-egroupware.org>
* @copyright (c) 2008-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de> * @author Ralf Becker <rb-AT-egroupware.org>
* @copyright (c) 2008-21 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
*/ */
@ -12,13 +13,13 @@
/api/js/jsapi/egw_app.js /api/js/jsapi/egw_app.js
*/ */
import 'jquery';
import 'jqueryui';
import '../jsapi/egw_global';
import '../etemplate/et2_types';
import {EgwApp, PushData} from '../../api/js/jsapi/egw_app'; import {EgwApp, PushData} from '../../api/js/jsapi/egw_app';
import {etemplate2} from "../../api/js/etemplate/etemplate2"; import {etemplate2} from "../../api/js/etemplate/etemplate2";
import {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog";
import {et2_selectbox} from "../../api/js/etemplate/et2_widget_selectbox";
import {nm_action, fetchAll} from "../../api/js/etemplate/et2_extension_nextmatch_actions.js";
import "./CRM.js";
import {egw} from "../../api/js/jsapi/egw_global";
/** /**
* Object to call app.addressbook.openCRMview with * Object to call app.addressbook.openCRMview with
@ -695,11 +696,11 @@ class AddressbookApp extends EgwApp
{ {
content.push({"confirm":id,"name":_data.doublicates[id]}); content.push({"confirm":id,"name":_data.doublicates[id]});
} }
confirmdialog(this.egw.lang('Duplicate warning'),content,et2_dialog.BUTTONs_OK_CANCEL); confirmdialog(this.egw.lang('Duplicate warning'),content,et2_dialog.BUTTONS_OK_CANCEL);
} }
if (typeof _data.fileas_options == 'object' && this.et2) if (typeof _data.fileas_options == 'object' && this.et2)
{ {
var selbox = this.et2.getWidgetById('fileas_type'); var selbox = <et2_selectbox>this.et2.getWidgetById('fileas_type');
if (selbox) if (selbox)
{ {
selbox.set_select_options(_data.fileas_sel_options); selbox.set_select_options(_data.fileas_sel_options);

View File

@ -46,6 +46,11 @@ function nm_action(_action, _senders, _target, _ids)
_ids = nm.getSelection(); _ids = nm.getSelection();
_action.data.nextmatch = nm; _action.data.nextmatch = nm;
} }
else
{
// This will probably fail without nm, but it depends on the action
_ids = {ids: _senders.map(function(s) {return s.id;})};
}
} }
// row ids // row ids
var row_ids = ""; var row_ids = "";

View File

@ -31,6 +31,7 @@ class Merge extends Api\Storage\Merge
var $public_functions = array( var $public_functions = array(
'download_by_request' => true, 'download_by_request' => true,
'show_replacements' => true, 'show_replacements' => true,
"merge_entries" => true
); );
/** /**

View File

@ -15,6 +15,7 @@ namespace EGroupware\Api\Storage;
use DOMDocument; use DOMDocument;
use EGroupware\Api; use EGroupware\Api;
use EGroupware\Api\Vfs;
use EGroupware\Stylite; use EGroupware\Stylite;
use tidy; use tidy;
use uiaccountsel; use uiaccountsel;
@ -77,6 +78,9 @@ abstract class Merge
public $export_limit; public $export_limit;
public $public_functions = array(
"merge_entries" => true
);
/** /**
* Configuration for HTML Tidy to clean up any HTML content that is kept * Configuration for HTML Tidy to clean up any HTML content that is kept
*/ */
@ -2083,10 +2087,6 @@ abstract class Merge
{ {
self::document_mail_action($documents['document'], $file); self::document_mail_action($documents['document'], $file);
} }
else if ($editable_mimes[$file['mime']])
{
self::document_editable_action($documents['document'], $file);
}
} }
$files = array(); $files = array();
@ -2164,10 +2164,6 @@ abstract class Merge
{ {
self::document_mail_action($current_level[$prefix.$file['name']], $file); self::document_mail_action($current_level[$prefix.$file['name']], $file);
} }
else if ($editable_mimes[$file['mime']])
{
self::document_editable_action($current_level[$prefix.$file['name']], $file);
}
break; break;
default: default:
@ -2198,16 +2194,21 @@ abstract class Merge
} }
$documents[$file['mime']]['children'][$prefix.$file['name']] = array( $documents[$file['mime']]['children'][$prefix.$file['name']] = array(
'caption' => Api\Vfs::decodePath($file['name']), 'caption' => Api\Vfs::decodePath($file['name']),
'target' => '_blank',
'postSubmit' => true, // download needs post submit (not Ajax) to work 'postSubmit' => true, // download needs post submit (not Ajax) to work
); );
$edit_attributes = array(
'menuaction' => $GLOBALS['egw_info']['flags']['currentapp'].'.'.get_called_class().'.merge_entries',
'document' => $file['path'],
'merge' => get_called_class(),
'id' => '$id',
'select_all' => '$select_all'
);
$documents[$file['mime']]['children'][$prefix.$file['name']]['url'] = urldecode(http_build_query($edit_attributes));
if ($file['mime'] == 'message/rfc822') if ($file['mime'] == 'message/rfc822')
{ {
self::document_mail_action($documents[$file['mime']]['children'][$prefix.$file['name']], $file); self::document_mail_action($documents[$file['mime']]['children'][$prefix.$file['name']], $file);
} }
else if ($editable_mimes[$file['mime']])
{
self::document_editable_action($documents[$file['mime']]['children'][$prefix.$file['name']], $file);
}
} }
else else
{ {
@ -2215,16 +2216,21 @@ abstract class Merge
'icon' => Api\Vfs::mime_icon($file['mime']), 'icon' => Api\Vfs::mime_icon($file['mime']),
'caption' => Api\Vfs::decodePath($file['name']), 'caption' => Api\Vfs::decodePath($file['name']),
'group' => 2, 'group' => 2,
'postSubmit' => true, // download needs post submit (not Ajax) to work 'target' => '_blank'
); );
$edit_attributes = array(
'menuaction' => $GLOBALS['egw_info']['flags']['currentapp'].'.'.get_called_class().'.merge_entries',
'document' => $file['path'],
'merge' => get_called_class(),
'id' => '$id',
'select_all' => '$select_all'
);
$documents[$prefix.$file['name']]['url'] = urldecode(http_build_query($edit_attributes));
if ($file['mime'] == 'message/rfc822') if ($file['mime'] == 'message/rfc822')
{ {
self::document_mail_action($documents[$prefix.$file['name']], $file); self::document_mail_action($documents[$prefix.$file['name']], $file);
} }
else if ($editable_mimes[$file['mime']])
{
self::document_editable_action($documents[$prefix.$file['name']], $file);
}
} }
} }
@ -2286,15 +2292,14 @@ abstract class Merge
private static function document_editable_action(Array &$action, $file) private static function document_editable_action(Array &$action, $file)
{ {
unset($action['postSubmit']); unset($action['postSubmit']);
$action['nm_action'] = 'location'; $edit_attributes = array(
$action['url'] = urldecode(http_build_query(array(
'menuaction' => 'collabora.EGroupware\\collabora\\Ui.merge_edit', 'menuaction' => 'collabora.EGroupware\\collabora\\Ui.merge_edit',
'document' => $file['path'], 'document' => $file['path'],
'merge' => get_called_class(), 'merge' => get_called_class(),
'id' => '$id', 'id' => '$id',
'select_all' => '$select_all' 'select_all' => '$select_all'
))); );
$action['target'] = '_blank'; $action['url'] = urldecode(http_build_query($edit_attributes));
} }
/** /**
@ -2331,6 +2336,167 @@ abstract class Merge
return lang("Document '%1' does not exist or is not readable for you!",$document); return lang("Document '%1' does not exist or is not readable for you!",$document);
} }
/**
* Merge the selected IDs into the given document, save it to the VFS, then
* either open it in the editor or have the browser download the file.
*/
public static function merge_entries()
{
if (class_exists($_REQUEST['merge']) && is_subclass_of($_REQUEST['merge'], 'EGroupware\\Api\\Storage\\Merge'))
{
$document_merge = new $_REQUEST['merge']();
}
else
{
$document_merge = new Api\Contacts\Merge();
}
if(($error = $document_merge->check_document($_REQUEST['document'],'')))
{
$response->error($error);
return;
}
$ids = is_string($_REQUEST['id']) && strpos($_REQUEST['id'],'[') === FALSE ? explode(',',$_REQUEST['id']) : json_decode($_REQUEST['id'],true);
if($_REQUEST['select_all'] === 'true')
{
$ids = self::get_all_ids($document_merge);
}
$filename = '';
$result = $document_merge->merge_file($_REQUEST['document'], $ids, $filename, '', $header);
if(!is_file($result) || !is_readable($result))
{
throw new Api\Exception\AssertionFailed("Unable to generate merge file\n". $result);
}
// Put it into the vfs using user's configured home dir if writable,
// or expected home dir (/home/username) if not
$target = $_target = (Vfs::is_writable(Vfs::get_home_dir()) ?
Vfs::get_home_dir() :
"/home/{$GLOBALS['egw_info']['user']['account_lid']}"
)."/$filename";
$dupe_count = 0;
while(is_file(Vfs::PREFIX.$target))
{
$dupe_count++;
$target = Vfs::dirname($_target) . '/' .
pathinfo($filename, PATHINFO_FILENAME) .
' ('.($dupe_count + 1).')' . '.' .
pathinfo($filename, PATHINFO_EXTENSION);
}
copy($result, Vfs::PREFIX.$target);
unlink($result);
// Find out what to do with it
$editable_mimes = array();
try {
if (class_exists('EGroupware\\collabora\\Bo') &&
$GLOBALS['egw_info']['user']['apps']['collabora'] &&
($discovery = \EGroupware\collabora\Bo::discover()) &&
$GLOBALS['egw_info']['user']['preferences']['filemanager']['merge_open_handler'] != 'download'
)
{
$editable_mimes = $discovery;
}
}
catch (\Exception $e)
{
// ignore failed discovery
unset($e);
}
if($editable_mimes[Vfs::mime_content_type($target)])
{
\Egroupware\Api\Egw::redirect_link('/index.php', array(
'menuaction' => 'collabora.EGroupware\\Collabora\\Ui.editor',
'path'=> $target
));
}
else
{
\Egroupware\Api\Egw::redirect_link(Vfs::download_url($target));
}
}
/**
* Get all ids for when they try to do 'Select All', then merge into document
*
* @param Api\Contacts\Merge $merge App-specific merge object
*/
protected function get_all_ids(Api\Storage\Merge $merge)
{
$ids = array();
$locations = array('index', 'session_data');
// Get app
list($appname, $_merge) = explode('_', get_class($merge));
if($merge instanceOf Api\Contacts\Merge)
{
$appname = 'addressbook';
}
switch(get_class($merge))
{
case \calendar_merge::class:
$ui_class = 'calendar_uilist';
$locations = array('calendar_list');
break;
case \projectmanager_merge::class;
$ui_class = 'projectmanager_ui';
$locations = array('project_list');
break;
default:
$ui_class = $appname . '_ui';
break;
}
// Ask app
if(class_exists($ui_class))
{
$ui = new $ui_class();
if( method_exists($ui_class, 'get_all_ids') )
{
return $ui->get_all_ids();
}
// Try cache
if( method_exists($ui_class, 'get_rows'))
{
foreach($locations as $location)
{
$session = Api\Cache::getSession($appname, $location);
if($session && $session['row_id'])
{
break;
}
}
$rows = $readonlys = array();
@set_time_limit(0); // switch off the execution time limit, as it's for big selections to small
$session['num_rows'] = -1; // all
$ui->get_rows($session, $rows, $readonlys);
foreach($rows as $row_number => $row)
{
if(!is_numeric($row_number)) continue;
$row_id = $row[$session['row_id'] ? $session['row_id'] : 'id'];
switch (get_class($merge))
{
case \calendar_merge::class:
$explody = explode(':',$row_id);
$ids[] = array('id' => $explody[0], 'recur_date' => $explody[1]);
break;
case \timesheet_merge::class:
// Skip the rows with totalss
if(!is_numeric($row_id)) continue 2; // +1 for switch
// Fall through
default:
$ids[] = $row_id;
}
}
}
}
return $ids;
}
/** /**
* Get a list of supported extentions * Get a list of supported extentions
*/ */