forked from extern/egroupware
* Add preference to set the filename of merged documents using placeholders
This commit is contained in:
parent
5b3a6c02b4
commit
45f039da95
@ -304,17 +304,27 @@ class addressbook_hooks
|
||||
'admin' => False,
|
||||
);
|
||||
$settings['document_dir'] = array(
|
||||
'type' => 'vfs_dirs',
|
||||
'size' => 60,
|
||||
'label' => 'Directory with documents to insert contacts',
|
||||
'name' => 'document_dir',
|
||||
'help' => lang('If you specify a directory (full vfs path) here, %1 displays an action for each document. That action allows to download the specified document with the data inserted.',lang('addressbook')).' '.
|
||||
lang('The document can contain placeholder like {{%1}}, to be replaced with the data.','n_fn').' '.
|
||||
lang('The following document-types are supported:'). implode(',',Api\Storage\Merge::get_file_extensions()),
|
||||
'type' => 'vfs_dirs',
|
||||
'size' => 60,
|
||||
'label' => 'Directory with documents to insert contacts',
|
||||
'name' => 'document_dir',
|
||||
'help' => lang('If you specify a directory (full vfs path) here, %1 displays an action for each document. That action allows to download the specified document with the data inserted.', lang('addressbook')) . ' ' .
|
||||
lang('The document can contain placeholder like {{%1}}, to be replaced with the data.', 'n_fn') . ' ' .
|
||||
lang('The following document-types are supported:') . implode(',', Api\Storage\Merge::get_file_extensions()),
|
||||
'run_lang' => false,
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => '/templates/addressbook',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => '/templates/addressbook',
|
||||
);
|
||||
$settings[Api\Storage\Merge::PREF_DOCUMENT_FILENAME] = array(
|
||||
'type' => 'taglist',
|
||||
'label' => 'Document download filename',
|
||||
'name' => 'document_download_name',
|
||||
'values' => Api\Storage\Merge::DOCUMENT_FILENAME_OPTIONS,
|
||||
'help' => 'Choose the default filename for downloaded documents.',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => 'document',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -32,9 +32,26 @@ use ZipArchive;
|
||||
*/
|
||||
abstract class Merge
|
||||
{
|
||||
|
||||
/**
|
||||
* Preference, path where we will put the generated document
|
||||
*/
|
||||
const PREF_STORE_LOCATION = "merge_store_path";
|
||||
|
||||
/**
|
||||
* Preference, placeholders for creating the filename of the generated document
|
||||
*/
|
||||
const PREF_DOCUMENT_FILENAME = "document_download_name";
|
||||
|
||||
/**
|
||||
* List of placeholders
|
||||
*/
|
||||
const DOCUMENT_FILENAME_OPTIONS = [
|
||||
'$$document$$' => 'Template name',
|
||||
'$$link_title$$' => 'Entry link-title',
|
||||
'$$contact_title$$' => 'Contact link-title',
|
||||
'$$current_date$$' => 'Current date',
|
||||
];
|
||||
|
||||
/**
|
||||
* Instance of the addressbook_bo class
|
||||
*
|
||||
@ -246,47 +263,59 @@ abstract class Merge
|
||||
$replacements = array();
|
||||
foreach(array_keys($this->contacts->contact_fields) as $name)
|
||||
{
|
||||
$value = $contact[$name] ?? null;
|
||||
$value = $contact[$name] ?? '';
|
||||
if(!$value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch($name)
|
||||
{
|
||||
case 'created': case 'modified':
|
||||
if($value) $value = Api\DateTime::to($value);
|
||||
case 'created':
|
||||
case 'modified':
|
||||
if($value)
|
||||
{
|
||||
$value = Api\DateTime::to($value);
|
||||
}
|
||||
break;
|
||||
case 'bday':
|
||||
if ($value)
|
||||
if($value)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
$value = Api\DateTime::to($value, true);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
unset($e); // ignore exception caused by wrongly formatted date
|
||||
catch (\Exception $e)
|
||||
{
|
||||
unset($e); // ignore exception caused by wrongly formatted date
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'owner': case 'creator': case 'modifier':
|
||||
case 'owner':
|
||||
case 'creator':
|
||||
case 'modifier':
|
||||
$value = Api\Accounts::username($value);
|
||||
break;
|
||||
case 'cat_id':
|
||||
if ($value)
|
||||
if($value)
|
||||
{
|
||||
// if cat-tree is displayed, we return a full category path not just the name of the cat
|
||||
$use = $GLOBALS['egw_info']['server']['cat_tab'] == 'Tree' ? 'path' : 'name';
|
||||
$cats = array();
|
||||
foreach(is_array($value) ? $value : explode(',',$value) as $cat_id)
|
||||
foreach(is_array($value) ? $value : explode(',', $value) as $cat_id)
|
||||
{
|
||||
$cats[] = $GLOBALS['egw']->categories->id2name($cat_id,$use);
|
||||
$cats[] = $GLOBALS['egw']->categories->id2name($cat_id, $use);
|
||||
}
|
||||
$value = implode(', ',$cats);
|
||||
$value = implode(', ', $cats);
|
||||
}
|
||||
break;
|
||||
case 'jpegphoto': // returning a link might make more sense then the binary photo
|
||||
if ($contact['photo'])
|
||||
case 'jpegphoto': // returning a link might make more sense then the binary photo
|
||||
if($contact['photo'])
|
||||
{
|
||||
$value = Api\Framework::getUrl(Api\Framework::link('/index.php',$contact['photo']));
|
||||
$value = Api\Framework::getUrl(Api\Framework::link('/index.php', $contact['photo']));
|
||||
}
|
||||
break;
|
||||
case 'tel_prefer':
|
||||
if ($value && $contact[$value])
|
||||
if($value && $contact[$value])
|
||||
{
|
||||
$value = $contact[$value];
|
||||
}
|
||||
@ -1615,7 +1644,7 @@ abstract class Merge
|
||||
public static function get_app_class($appname)
|
||||
{
|
||||
$classname = "{$appname}_merge";
|
||||
if(class_exists($classname) && is_subclass_of($classname, 'EGroupware\\Api\\Storage\\Merge'))
|
||||
if(class_exists($classname, false) && is_subclass_of($classname, 'EGroupware\\Api\\Storage\\Merge'))
|
||||
{
|
||||
$document_merge = new $classname();
|
||||
}
|
||||
@ -1644,14 +1673,9 @@ abstract class Merge
|
||||
|
||||
try
|
||||
{
|
||||
$classname = "{$app}_merge";
|
||||
if(!class_exists($classname))
|
||||
{
|
||||
return $replacements;
|
||||
}
|
||||
$class = new $classname();
|
||||
$method = $app.'_replacements';
|
||||
if(method_exists($class,$method))
|
||||
$class = $this->get_app_class($app);
|
||||
$method = $app . '_replacements';
|
||||
if(method_exists($class, $method))
|
||||
{
|
||||
$replacements = $class->$method($id, $prefix, $content);
|
||||
}
|
||||
@ -2447,7 +2471,7 @@ abstract class Merge
|
||||
$pdf = (boolean)$_REQUEST['pdf'];
|
||||
}
|
||||
|
||||
$filename = $document_merge->get_filename($_REQUEST['document']);
|
||||
$filename = $document_merge->get_filename($_REQUEST['document'], $ids);
|
||||
$result = $document_merge->merge_file($_REQUEST['document'], $ids, $filename, '', $header);
|
||||
|
||||
if(!is_file($result) || !is_readable($result))
|
||||
@ -2519,12 +2543,54 @@ abstract class Merge
|
||||
/**
|
||||
* Generate a filename for the merged file, without extension
|
||||
*
|
||||
* Default is just the name of the template
|
||||
* Default filename is just the name of the template.
|
||||
* We use the placeholders from get_filename_placeholders() and the application's document filename preference
|
||||
* to generate a custom filename.
|
||||
*
|
||||
* @param string $document Template filename
|
||||
* @param string[] $ids List of IDs being merged
|
||||
* @return string
|
||||
*/
|
||||
protected function get_filename($document) : string
|
||||
protected function get_filename($document, $ids = []) : string
|
||||
{
|
||||
return '';
|
||||
$name = '';
|
||||
if(isset($GLOBALS['egw_info']['user']['preferences'][$this->get_app()][static::PREF_DOCUMENT_FILENAME]))
|
||||
{
|
||||
$pref = $GLOBALS['egw_info']['user']['preferences'][$this->get_app()][static::PREF_DOCUMENT_FILENAME];
|
||||
$placeholders = $this->get_filename_placeholders($document, $ids);
|
||||
|
||||
// Make values safe for VFS
|
||||
foreach($placeholders as &$value)
|
||||
{
|
||||
$value = Api\Mail::clean_subject_for_filename($value);
|
||||
}
|
||||
|
||||
// Do replacement
|
||||
$name = str_replace(
|
||||
array_keys($placeholders),
|
||||
array_values($placeholders),
|
||||
is_array($pref) ? implode(' ', $pref) : $pref
|
||||
);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
protected function get_filename_placeholders($document, $ids)
|
||||
{
|
||||
$ext = '.' . pathinfo($document, PATHINFO_EXTENSION);
|
||||
$link_title = count($ids) == 1 ? Api\Link::title($this->get_app(), $ids[0]) : lang("multiple");
|
||||
$contact_title = count($ids) == 1 ? Api\Link::title($this->get_app(), $ids[0]) : lang("multiple");
|
||||
$current_date = str_replace('/', '-', Api\DateTime::to('now', Api\DateTime::$user_dateformat));
|
||||
|
||||
|
||||
$values = [
|
||||
'$$document$$' => basename($document, $ext),
|
||||
'$$link_title$$' => $link_title,
|
||||
'$$contact_title$$' => $contact_title,
|
||||
'$$current_date$$' => $current_date
|
||||
];
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -471,17 +471,27 @@ class infolog_hooks
|
||||
'admin' => False,
|
||||
);
|
||||
$settings['document_dir'] = array(
|
||||
'type' => 'vfs_dirs',
|
||||
'size' => 60,
|
||||
'label' => 'Directory with documents to insert entries',
|
||||
'name' => 'document_dir',
|
||||
'help' => lang('If you specify a directory (full vfs path) here, %1 displays an action for each document. That action allows to download the specified document with the data inserted.',lang('infolog')).' '.
|
||||
lang('The document can contain placeholder like {{%1}}, to be replaced with the data.','info_subject').' '.
|
||||
lang('The following document-types are supported:').'*.rtf, *.txt',
|
||||
'type' => 'vfs_dirs',
|
||||
'size' => 60,
|
||||
'label' => 'Directory with documents to insert entries',
|
||||
'name' => 'document_dir',
|
||||
'help' => lang('If you specify a directory (full vfs path) here, %1 displays an action for each document. That action allows to download the specified document with the data inserted.', lang('infolog')) . ' ' .
|
||||
lang('The document can contain placeholder like {{%1}}, to be replaced with the data.', 'info_subject') . ' ' .
|
||||
lang('The following document-types are supported:') . '*.rtf, *.txt',
|
||||
'run_lang' => false,
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => '/templates/infolog',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => '/templates/infolog',
|
||||
);
|
||||
$settings[Api\Storage\Merge::PREF_DOCUMENT_FILENAME] = array(
|
||||
'type' => 'taglist',
|
||||
'label' => 'Document download filename',
|
||||
'name' => 'document_download_name',
|
||||
'values' => Api\Storage\Merge::DOCUMENT_FILENAME_OPTIONS,
|
||||
'help' => 'Choose the default filename for downloaded documents.',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => 'document',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -64,23 +64,42 @@ class infolog_merge extends Api\Storage\Merge
|
||||
* @param string &$content=null content to create some replacements only if they are use
|
||||
* @return array|boolean
|
||||
*/
|
||||
protected function get_replacements($id,&$content=null)
|
||||
protected function get_replacements($id, &$content = null)
|
||||
{
|
||||
if (!($replacements = $this->infolog_replacements($id, '', $content)))
|
||||
if(!($replacements = $this->infolog_replacements($id, '', $content)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return $replacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override contact filename placeholder to use info_contact
|
||||
*
|
||||
* @param $document
|
||||
* @param $ids
|
||||
* @return array|void
|
||||
*/
|
||||
public function get_filename_placeholders($document, $ids)
|
||||
{
|
||||
$placeholders = parent::get_filename_placeholders($document, $ids);
|
||||
if(count($ids) == 1 && ($info = $this->bo->read($ids[0])))
|
||||
{
|
||||
$placeholders['$$contact_title$$'] = $info['info_contact']['title'] ??
|
||||
(is_array($info['info_contact']) && Link::title($info['info_contact']['app'], $info['info_contact']['id'])) ??
|
||||
'';
|
||||
}
|
||||
return $placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get infolog replacements
|
||||
*
|
||||
* @param int $id id of entry
|
||||
* @param string $prefix='' prefix like eg. 'erole'
|
||||
* @param string $prefix ='' prefix like eg. 'erole'
|
||||
* @return array|boolean
|
||||
*/
|
||||
public function infolog_replacements($id,$prefix='', &$content = '')
|
||||
public function infolog_replacements($id, $prefix = '', &$content = '')
|
||||
{
|
||||
$record = new infolog_egw_record($id);
|
||||
$info = array();
|
||||
|
@ -191,17 +191,27 @@ class timesheet_hooks
|
||||
'admin' => False,
|
||||
);
|
||||
$settings['document_dir'] = array(
|
||||
'type' => 'vfs_dirs',
|
||||
'size' => 60,
|
||||
'label' => 'Directory with documents to insert entries',
|
||||
'name' => 'document_dir',
|
||||
'help' => lang('If you specify a directory (full vfs path) here, %1 displays an action for each document. That action allows to download the specified document with the %1 data inserted.', lang('timesheet')).' '.
|
||||
lang('The document can contain placeholder like {{%1}}, to be replaced with the data.','ts_title').' '.
|
||||
lang('The following document-types are supported:'). implode(',',Api\Storage\Merge::get_file_extensions()),
|
||||
'type' => 'vfs_dirs',
|
||||
'size' => 60,
|
||||
'label' => 'Directory with documents to insert entries',
|
||||
'name' => 'document_dir',
|
||||
'help' => lang('If you specify a directory (full vfs path) here, %1 displays an action for each document. That action allows to download the specified document with the %1 data inserted.', lang('timesheet')) . ' ' .
|
||||
lang('The document can contain placeholder like {{%1}}, to be replaced with the data.', 'ts_title') . ' ' .
|
||||
lang('The following document-types are supported:') . implode(',', Api\Storage\Merge::get_file_extensions()),
|
||||
'run_lang' => false,
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => '/templates/timesheet',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => '/templates/timesheet',
|
||||
);
|
||||
$settings[Api\Storage\Merge::PREF_DOCUMENT_FILENAME] = array(
|
||||
'type' => 'taglist',
|
||||
'label' => 'Document download filename',
|
||||
'name' => 'document_download_name',
|
||||
'values' => Api\Storage\Merge::DOCUMENT_FILENAME_OPTIONS,
|
||||
'help' => 'Choose the default filename for downloaded documents.',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
'default' => 'document',
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user