Add merge functionallity to infolog

This commit is contained in:
Nathan Gray 2011-01-26 20:16:18 +00:00
parent ec4ef57ed0
commit 116523ccfd
4 changed files with 365 additions and 3 deletions

View File

@ -370,6 +370,36 @@ class infolog_hooks
'default'=> '0d', // Same day
);
// Merge print
if ($GLOBALS['egw_info']['user']['apps']['filemanager'])
{
$link = egw::link('/index.php','menuaction=infolog.infolog_merge.show_replacements');
$settings['default_document'] = array(
'type' => 'input',
'size' => 60,
'label' => 'Default document to insert entries',
'name' => 'default_document',
'help' => lang('If you specify a document (full vfs path) here, infolog displays an extra document icon for each entry. That icon allows to download the specified document with the contact data inserted.').' '.
lang('The document can contain placeholder like $$info_subject$$, to be replaced with the contact data (%1full list of placeholder names%2).','<a href="'.$link.'" target="_blank">','</a>').' '.
lang('At the moment the following document-types are supported:').'*.rtf, *.txt',
'run_lang' => false,
'xmlrpc' => True,
'admin' => False,
);
$settings['document_dir'] = array(
'type' => 'input',
'size' => 60,
'label' => 'Directory with documents to insert entries',
'name' => 'document_dir',
'help' => lang('If you specify a directory (full vfs path) here, infolog displays an action for each document. That action allows to download the specified document with the infolog data inserted.').' '.
lang('The document can contain placeholder like $$info_subject$$, to be replaced with the contact data (%1full list of placeholder names%2).','<a href="'.$link.'" target="_blank">','</a>').' '.
lang('At the moment the following document-types are supported:').'*.rtf, *.txt',
'run_lang' => false,
'xmlrpc' => True,
'admin' => False,
);
}
return $settings;
}

View File

@ -0,0 +1,261 @@
<?php
/**
* Infolog - document merge
*
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @author Nathan Gray
* @package infolog
* @copyright (c) 2007-9 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright 2011 Nathan Gray
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
/**
* Infolog - document merge object
*/
class infolog_merge extends bo_merge
{
/**
* Functions that can be called via menuaction
*
* @var array
*/
var $public_functions = array('show_replacements' => true);
/**
* Business object to pull records from
*/
protected $bo = null;
/**
* Constructor
*
*/
function __construct()
{
parent::__construct();
$this->bo = new infolog_bo();
}
/**
* Get infolog replacements
*
* @param int $id id of entry
* @param string &$content=null content to create some replacements only if they are use
* @param array $eroles=null element roles with keys app, app_id and erole_id
* @return array|boolean
*/
protected function get_replacements($id,&$content=null,$eroles=null)
{
if (!($replacements = $this->infolog_replacements($id)))
{
return false;
}
if (!(strpos($content,'$$calendar/') === false))
{
$replacements += $this->calendar_replacements($id,!(strpos($content,'$$calendar/-1/') === false));
}
return $replacements;
}
/**
* Get infolog replacements
*
* @param int $id id of entry
* @return array|boolean
*/
protected function infolog_replacements($id)
{
$record = new infolog_egw_record($id);
$info = array();
// Convert to human friendly values
$types = infolog_export_csv::$types;
$_selects = $this->bo->enums + array('status' => $this->bo->status[$record->info_type]);
foreach($_selects as $name => $value)
{
$selects['info_'.$name] = $value;
$types['select'][] = 'info_'.$name;
}
importexport_export_csv::convert($record, $types, 'infolog', $selects);
if($record->info_contact)
{
$array['info_contact'] = $array['info_link']['title'];
}
// Set any missing custom fields, or the marker will stay
$array = $record->get_record_array();
foreach($this->bo->customfields as $name => $field)
{
if(!$array['#'.$name]) $array['#'.$name] = '';
}
// Add markers
foreach($array as $key => $value)
{
$info['$$' . $key . '$$'] = $value;
}
return $info;
}
/**
* Return replacements for the calendar (next events) of a contact
*
* @param int $contact contact-id
* @param boolean $last_event_too=false also include information about the last event
* @return array
*/
protected function calendar_replacements($id,$last_event_too=false)
{
$calendar = new calendar_boupdate();
// next events
$events = $calendar->search(array(
'start' => $calendar->now_su,
'users' => 'c'.$id,
'offset' => 0,
'num_rows' => 20,
'order' => 'cal_start',
));
if ($events)
{
array_unshift($events,false); unset($events[0]); // renumber the array to start with key 1, instead of 0
}
else
{
$events = array();
}
if ($last_event_too=true)
{
$last = $calendar->search(array(
'end' => $calendar->now_su,
'users' => 'c'.$id,
'offset' => 0,
'num_rows' => 1,
'order' => 'cal_start DESC',
));
if ($last) $events['-1'] = array_shift($last); // returned events are indexed by cal_id!
}
$replacements = array();
foreach($events as $n => $event)
{
foreach($calendar->event2array($event) as $name => $data)
{
if (substr($name,-4) == 'date') $name = substr($name,0,-4);
$replacements['$$calendar/'.$n.'/'.$name.'$$'] = is_array($data['data']) ? implode(', ',$data['data']) : $data['data'];
}
foreach(array('start','end') as $what)
{
foreach(array(
'date' => $GLOBALS['egw_info']['user']['preferences']['common']['dateformat'],
'day' => 'l',
'time' => $GLOBALS['egw_info']['user']['preferences']['common']['timeformat'] == 12 ? 'h:i a' : 'H:i',
) as $name => $format)
{
$value = date($format,$event[$what]);
if ($format == 'l') $value = lang($value);
$replacements['$$calendar/'.$n.'/'.$what.$name.'$$'] = $value;
}
}
$duration = ($event['end'] - $event['start'])/60;
$replacements['$$calendar/'.$n.'/duration$$'] = floor($duration/60).lang('h').($duration%60 ? $duration%60 : '');
++$n;
}
return $replacements;
}
/**
* Generate table with replacements for the preferences
*
*/
public function show_replacements()
{
$GLOBALS['egw_info']['flags']['app_header'] = lang('infolog').' - '.lang('Replacements for inserting entries into documents');
$GLOBALS['egw_info']['flags']['nonavbar'] = false;
common::egw_header();
echo "<table width='90%' align='center'>\n";
echo '<tr><td colspan="4"><h3>'.lang('Infolog fields:')."</h3></td></tr>";
$n = 0;
$tracking = new infolog_tracking($this->bo);
foreach($tracking->field2label as $name => $label)
{
if (in_array($name,array('custom'))) continue; // dont show them
if (in_array($name,array('info_subject', 'info_des')) && $n&1) // main values, which should be in the first column
{
echo "</tr>\n";
$n++;
}
if (!($n&1)) echo '<tr>';
echo '<td>$$'.$name.'$$</td><td>'.$label.'</td>';
if ($n&1) echo "</tr>\n";
$n++;
}
echo '<tr><td colspan="4"><h3>'.lang('Custom fields').":</h3></td></tr>";
foreach($this->bo->customfields as $name => $field)
{
echo '<tr><td>$$#'.$name.'$$</td><td colspan="3">'.$field['label']."</td></tr>\n";
}
echo '<tr><td colspan="4"><h3>'.lang('General fields:')."</h3></td></tr>";
foreach(array(
'date' => lang('Date'),
'user/n_fn' => lang('Name of current user, all other contact fields are valid too'),
'user/account_lid' => lang('Username'),
'pagerepeat' => lang('For serial letter use this tag. Put the content, you want to repeat between two Tags.'),
'label' => lang('Use this tag for addresslabels. Put the content, you want to repeat, between two tags.'),
'labelplacement' => lang('Tag to mark positions for address labels'),
'IF fieldname' => lang('Example $$IF n_prefix~Mr~Hello Mr.~Hello Ms.$$ - search the field "n_prefix", for "Mr", if found, write Hello Mr., else write Hello Ms.'),
'NELF' => lang('Example $$NELF role$$ - if field role is not empty, you will get a new line with the value of field role'),
'NENVLF' => lang('Example $$NELFNV role$$ - if field role is not empty, set a LF without any value of the field'),
'LETTERPREFIX' => lang('Example $$LETTERPREFIX$$ - Gives a letter prefix without double spaces, if the title is emty for example'),
'LETTERPREFIXCUSTOM' => lang('Example $$LETTERPREFIXCUSTOM n_prefix title n_family$$ - Example: Mr Dr. James Miller'),
) as $name => $label)
{
echo '<tr><td>$$'.$name.'$$</td><td colspan="3">'.$label."</td></tr>\n";
}
$GLOBALS['egw']->translation->add_app('calendar');
echo '<tr><td colspan="4"><h3>'.lang('Calendar fields:')." # = 1, 2, ..., 20, -1</h3></td></tr>";
foreach(array(
'title' => lang('Title'),
'description' => lang('Description'),
'participants' => lang('Participants'),
'location' => lang('Location'),
'start' => lang('Start').': '.lang('Date').'+'.lang('Time'),
'startday' => lang('Start').': '.lang('Weekday'),
'startdate'=> lang('Start').': '.lang('Date'),
'starttime'=> lang('Start').': '.lang('Time'),
'end' => lang('End').': '.lang('Date').'+'.lang('Time'),
'endday' => lang('End').': '.lang('Weekday'),
'enddate' => lang('End').': '.lang('Date'),
'endtime' => lang('End').': '.lang('Time'),
'duration' => lang('Duration'),
'category' => lang('Category'),
'priority' => lang('Priority'),
'updated' => lang('Updated'),
'recur_type' => lang('Repetition'),
'access' => lang('Access').': '.lang('public').', '.lang('private'),
'owner' => lang('Owner'),
) as $name => $label)
{
if (in_array($name,array('start','end')) && $n&1) // main values, which should be in the first column
{
echo "</tr>\n";
$n++;
}
if (!($n&1)) echo '<tr>';
echo '<td>$$calendar/#/'.$name.'$$</td><td>'.$label.'</td>';
if ($n&1) echo "</tr>\n";
$n++;
}
echo "</table>\n";
common::egw_footer();
}
}

View File

@ -502,6 +502,13 @@ class infolog_ui
$GLOBALS['egw']->session->appsession('own_session','infolog',$own_referer);
}
}
if (is_array($values) && isset($values['nm']['rows']['document'])) // handle insert in default document button like an action
{
list($id) = @each($values['nm']['rows']['document']);
$values['multi_action'] = 'document';
$values['nm']['rows']['checked'] = array($id);
}
if (is_array($values) && isset($values['multi_action']) && $values['multi_action'] !== '')
{
if (!count($values['nm']['rows']['checked']) && !$values['use_all'])
@ -789,6 +796,12 @@ class infolog_ui
$change_status['status_'.$id] = $label;
}
$sel_options['multi_action'][lang('Change status:')] = $change_status;
// Merge print
if ($this->prefs['document_dir'])
{
$sel_options['multi_action'][lang('Insert in document').':'] = $this->get_document_actions();
}
egw_framework::validate_file('.','index','infolog');
return $this->tmpl->exec('infolog.infolog_ui.index',$values,$sel_options,$readonlys,$persist,$return_html ? -1 : 0);
@ -873,7 +886,11 @@ class infolog_ui
$success += $count;
}
}
break;
return ($failed == 0);
case 'document':
$msg = $this->download_document($checked,$settings);
$failed = count($checked);
return false;
}
// Actions that need to loop
@ -2004,4 +2021,58 @@ class infolog_ui
}
return $fields;
}
/**
* Returning document actions / files from the document_dir
*
* @return array
*/
function get_document_actions()
{
if (!$this->prefs['document_dir']) return array();
//if (!is_array($actions = egw_session::appsession('document_actions','infolog')))
//{
$actions = array();
if (($files = egw_vfs::find($this->prefs['document_dir'],array('need_mime'=>true),true)))
{
foreach($files as $file)
{
// return only the mime-types we support
if (!infolog_merge::is_implemented($file['mime'],substr($file['name'],-4))) continue;
$actions['document_'.$file['name']] = /*lang('Insert in document').': '.*/$file['name'];
}
}
egw_session::appsession('document_actions','infolog',$actions);
//}
return $actions;
}
/**
* Download a document with inserted entries
*
* @param array $ids infolog-ids
* @param string $document vfs-path of document
* @return string error-message or error, otherwise the function does NOT return!
*/
function download_document($ids,$document='')
{
if (!$document)
{
$document = $this->prefs['default_document'];
}
else
{
$document = $this->prefs['document_dir'].'/'.$document;
}
if (!@egw_vfs::stat($document))
{
return lang("Document '%1' does not exist or is not readable for you!",$document);
}
require_once(EGW_INCLUDE_ROOT.'/infolog/inc/class.infolog_merge.inc.php');
$document_merge = new infolog_merge();
return $document_merge->download($document,$ids);
}
}

File diff suppressed because one or more lines are too long