mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-16 04:53:18 +01:00
* Mail: Implement mail integration with new structure and add new feature
- Add mail to calendar as calendar entry, including all mail attachments as links - Add user choice for saving mail into an existing ticket or a new ticket - Fix mail attachments integration into infolog, tracker or calendar entry
This commit is contained in:
commit
50782cfa8b
@ -856,6 +856,19 @@ END:VALARM';
|
||||
unset($data); // not used, but in function signature for hooks
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mail integration hook to import mail message contents into a calendar entry
|
||||
*
|
||||
* @return string method to be executed for calendar mail integration
|
||||
*/
|
||||
public static function mail_import($args)
|
||||
{
|
||||
return array (
|
||||
'menuaction' => 'calendar.calendar_uiforms.mail_import',
|
||||
'popup' => egw_link::get_registry('calendar', 'edit_popup')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Not part of the class, since config hooks are still using the old style
|
||||
@ -879,4 +892,4 @@ function calendar_purge_old($config)
|
||||
$GLOBALS['config_error'] = 'Unable to schedule purge';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ class calendar_uiforms extends calendar_ui
|
||||
'import' => true,
|
||||
'cat_acl' => true,
|
||||
'meeting' => true,
|
||||
'mail_import' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
@ -1317,13 +1318,12 @@ class calendar_uiforms extends calendar_ui
|
||||
$event['whole_day'] = !$start['hour'] && !$start['minute'] && $end['hour'] == 23 && $end['minute'] == 59;
|
||||
|
||||
$link_to_id = $event['id'];
|
||||
if (!$add_link && !$event['id'] && isset($_REQUEST['link_app']) && isset($_REQUEST['link_id']))
|
||||
if (!$event['id'] && isset($_REQUEST['link_app']) && isset($_REQUEST['link_id']))
|
||||
{
|
||||
$link_ids = is_array($_REQUEST['link_id']) ? $_REQUEST['link_id'] : array($_REQUEST['link_id']);
|
||||
foreach(is_array($_REQUEST['link_app']) ? $_REQUEST['link_app'] : array($_REQUEST['link_app']) as $n => $link_app)
|
||||
{
|
||||
$link_id = $link_ids[$n];
|
||||
$app_entry = array();
|
||||
if(!preg_match('/^[a-z_0-9-]+:[:a-z_0-9-]+$/i',$link_app.':'.$link_id)) // guard against XSS
|
||||
{
|
||||
continue;
|
||||
@ -1687,9 +1687,9 @@ class calendar_uiforms extends calendar_ui
|
||||
* Display for FMail an iCal meeting request and allow to accept, tentative or reject it or a reply and allow to apply it
|
||||
*
|
||||
* @todo Handle situation when user is NOT invited, but eg. can view that mail ...
|
||||
* @param array $event=null; special usage if $event is array('event'=>null,'msg'=>'','useSession'=>true) we
|
||||
* @param array $event = null; special usage if $event is array('event'=>null,'msg'=>'','useSession'=>true) we
|
||||
* are called by new mail-app; and we intend to use the stuff passed on by session
|
||||
* @param string $msg=null
|
||||
* @param string $msg = null
|
||||
*/
|
||||
function meeting(array $event=null, $msg=null)
|
||||
{
|
||||
@ -1866,7 +1866,7 @@ class calendar_uiforms extends calendar_ui
|
||||
$event['ics_method_label'] = strtolower($ical_method) == 'request' ?
|
||||
lang('Meeting request') : lang('Reply to meeting request');
|
||||
$tpl = new etemplate_new('calendar.meeting');
|
||||
$tpl->exec('calendar.calendar_uiforms.meeting', $event, $sel_options, $readonlys, $event, 2);
|
||||
$tpl->exec('calendar.calendar_uiforms.meeting', $event, array(), $readonlys, $event, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2058,7 +2058,7 @@ class calendar_uiforms extends calendar_ui
|
||||
{
|
||||
if (!$content['duration']) $content['duration'] = $content['end'] - $content['start'];
|
||||
$weekds = 0;
|
||||
foreach ($content['weekdays'] as $keys =>$wdays)
|
||||
foreach ($content['weekdays'] as &$wdays)
|
||||
{
|
||||
$weekds = $weekds + $wdays;
|
||||
}
|
||||
@ -2288,8 +2288,6 @@ class calendar_uiforms extends calendar_ui
|
||||
}
|
||||
if (!is_array($content))
|
||||
{
|
||||
$view = $GLOBALS['egw']->session->appsession('view','calendar');
|
||||
|
||||
$content = array(
|
||||
'start' => $this->bo->date2ts($_REQUEST['start'] ? $_REQUEST['start'] : $this->date),
|
||||
'end' => $this->bo->date2ts($_REQUEST['end'] ? $_REQUEST['end'] : $this->date),
|
||||
@ -2562,4 +2560,100 @@ class calendar_uiforms extends calendar_ui
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* imports a mail as Calendar
|
||||
*
|
||||
* @param array $mailContent = null mail content
|
||||
* @return array
|
||||
*/
|
||||
function mail_import(array $mailContent=null)
|
||||
{
|
||||
// It would get called from compose as a popup with egw_data
|
||||
if (!is_array($mailContent) && ($_GET['egw_data']))
|
||||
{
|
||||
// get raw mail data
|
||||
egw_link::get_data ($_GET['egw_data']);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($mailContent))
|
||||
{
|
||||
// Addressbook
|
||||
$AB = new addressbook_bo();
|
||||
$accounts = array(0 => $GLOBALS['egw_info']['user']['account_id']);
|
||||
|
||||
$participants[0] = array (
|
||||
'uid' => $GLOBALS['egw_info']['user']['account_id'],
|
||||
'delete_id' => $GLOBALS['egw_info']['user']['account_id'],
|
||||
'status' => 'A',
|
||||
'old_status' => 'A',
|
||||
'app' => 'User',
|
||||
'role' => 'REQ-PARTICIPANT'
|
||||
);
|
||||
foreach($mailContent['addresses'] as $address)
|
||||
{
|
||||
// Get available contacts from the email
|
||||
$contacts = $AB->search(array(
|
||||
'email' => $address['email'],
|
||||
'email_home' => $address['email']
|
||||
),'contact_id,contact_email,contact_email_home,egw_addressbook.account_id as account_id','','','',false,'OR',false,array('owner' => 0),'',false);
|
||||
if (is_array($contacts))
|
||||
{
|
||||
foreach($contacts as $account)
|
||||
{
|
||||
$accounts[] = $account['account_id'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$participants []= array (
|
||||
'app' => 'email',
|
||||
'uid' => 'e'.$address['email'],
|
||||
'status' => 'U',
|
||||
'old_status' => 'U'
|
||||
);
|
||||
}
|
||||
}
|
||||
$participants = array_merge($participants , array(
|
||||
"account" => $accounts,
|
||||
"role" => "REQ-PARTICIPANT",
|
||||
"add" => "pressed"
|
||||
));
|
||||
|
||||
// Prepare calendar event draft
|
||||
$event = array(
|
||||
'title' => $mailContent['subject'],
|
||||
'description' => $mailContent['message'],
|
||||
'participants' => $participants,
|
||||
'link_to' => array(
|
||||
'to_app' => 'calendar',
|
||||
'to_id' => 0,
|
||||
),
|
||||
'start' => $mailContent['date'],
|
||||
'duration' => 60 * $this->cal_prefs['interval']
|
||||
);
|
||||
|
||||
if (is_array($mailContent['attachments']))
|
||||
{
|
||||
foreach ($mailContent['attachments'] as $attachment)
|
||||
{
|
||||
if($attachment['egw_data'])
|
||||
{
|
||||
egw_link::link('calendar',$event['link_to']['to_id'],egw_link::DATA_APPNAME, $attachment);
|
||||
}
|
||||
else if(is_readable($attachment['tmp_name']))
|
||||
{
|
||||
egw_link::link('calendar',$event['link_to']['to_id'],'file', $attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
egw_framework::window_close(lang('No content found to show up as calendar entry.'));
|
||||
}
|
||||
|
||||
return $this->process_edit($event);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ $setup_info['calendar']['hooks']['infolog_set'] = 'calendar.calendar_bo.infolog_
|
||||
$setup_info['calendar']['hooks']['export_limit'] = 'calendar_hooks::getAppExportLimit';
|
||||
$setup_info['calendar']['hooks']['acl_rights'] = 'calendar_hooks::acl_rights';
|
||||
$setup_info['calendar']['hooks']['categories'] = 'calendar_hooks::categories';
|
||||
$setup_info['calendar']['hooks']['mail_import'] = 'calendar_hooks::mail_import';
|
||||
|
||||
/* Dependencies for this app to work */
|
||||
$setup_info['calendar']['depends'][] = array(
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1672,7 +1672,7 @@ var et2_link_list = et2_link_string.extend(
|
||||
link.dom_id = 'temp_'+egw.uid();
|
||||
}
|
||||
// Icon should be in registry
|
||||
if(typeof link.icon == 'undefined')
|
||||
if(!link.icon)
|
||||
{
|
||||
link.icon = egw.link_get_registry(link.app,'icon');
|
||||
// No icon, try by mime type - different place for un-saved entries
|
||||
@ -1684,7 +1684,7 @@ var et2_link_list = et2_link_string.extend(
|
||||
}
|
||||
}
|
||||
// Special handling for file - if not existing, we can't ask for title
|
||||
if(link.app == 'file' && typeof link.title == 'undefined')
|
||||
if(typeof link.id =='object' && !link.title)
|
||||
{
|
||||
link.title = link.id.name || '';
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ class infolog_bo
|
||||
* checks if there are customfields for typ $typ
|
||||
*
|
||||
* @param string $type
|
||||
* @param boolean $links=false if true check only customfields containing links, default false = all custom fields
|
||||
* @param boolean $links = false if true check only customfields containing links, default false = all custom fields
|
||||
* @return boolean True if there are customfields for $typ, else False
|
||||
*/
|
||||
function has_customfields($type,$links=false)
|
||||
@ -321,7 +321,7 @@ class infolog_bo
|
||||
* @param int|array $info data or info_id of infolog entry to check
|
||||
* @param int $required_rights EGW_ACL_{READ|EDIT|ADD|DELETE}
|
||||
* @param int $other uid to check (if info==0) or 0 to check against $this->user
|
||||
* @param int $user=null user whos rights to check, default current user
|
||||
* @param int $user = null user whos rights to check, default current user
|
||||
* @return boolean
|
||||
*/
|
||||
function check_access($info,$required_rights,$other=0,$user=null)
|
||||
@ -413,8 +413,8 @@ class infolog_bo
|
||||
* convert a link_id value into an info_from text
|
||||
*
|
||||
* @param array &$info infolog entry, key info_from gets set by this function
|
||||
* @param string $not_app='' app to exclude
|
||||
* @param string $not_id='' id to exclude
|
||||
* @param string $not_app = '' app to exclude
|
||||
* @param string $not_id = '' id to exclude
|
||||
* @return boolean True if we have a linked item, False otherwise
|
||||
*/
|
||||
function link_id2from(&$info,$not_app='',$not_id='')
|
||||
@ -482,8 +482,8 @@ class infolog_bo
|
||||
* and $fromTZId is only used to qualify dates.
|
||||
*
|
||||
* @param array $values to modify
|
||||
* @param string $fromTZId=null
|
||||
* @param string $toTZId=false
|
||||
* @param string $fromTZId = null
|
||||
* @param string $toTZId = false
|
||||
* TZID timezone name e.g. 'UTC'
|
||||
* or NULL for timestamps in user-time
|
||||
* or false for timestamps in server-time
|
||||
@ -555,7 +555,7 @@ class infolog_bo
|
||||
* convert a date from server to user-time
|
||||
*
|
||||
* @param int $ts timestamp in server-time
|
||||
* @param string $date_format='ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time, 'array'=array or string with date-format
|
||||
* @param string $date_format = 'ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time, 'array'=array or string with date-format
|
||||
* @return mixed depending of $date_format
|
||||
*/
|
||||
function date2usertime($ts,$date_format='ts')
|
||||
@ -569,11 +569,11 @@ class infolog_bo
|
||||
* Read an infolog entry specified by $info_id
|
||||
*
|
||||
* @param int|array $info_id integer id or array with id's or array with column=>value pairs of the entry to read
|
||||
* @param boolean $run_link_id2from=true should link_id2from run, default yes,
|
||||
* @param boolean $run_link_id2from = true should link_id2from run, default yes,
|
||||
* need to be set to false if called from link-title to prevent an infinit recursion
|
||||
* @param string $date_format='ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time,
|
||||
* @param string $date_format = 'ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time,
|
||||
* 'array'=array or string with date-format
|
||||
* @param boolean $ignore_acl=false if true, do NOT check access, default false
|
||||
* @param boolean $ignore_acl = false if true, do NOT check access, default false
|
||||
*
|
||||
* @return array|boolean infolog entry, null if not found or false if no permission to read it
|
||||
*/
|
||||
@ -705,12 +705,12 @@ class infolog_bo
|
||||
* checks and asures ACL
|
||||
*
|
||||
* @param array &$values values to write
|
||||
* @param boolean $check_defaults=true check and set certain defaults
|
||||
* @param boolean|int $touch_modified=true touch the modification date and sets the modifier's user-id, 2: only modifier
|
||||
* @param boolean $user2server=true conversion between user- and server-time necessary
|
||||
* @param boolean $skip_notification=false true = do NOT send notification, false (default) = send notifications
|
||||
* @param boolean $throw_exception=false Throw an exception (if required fields are not set)
|
||||
* @param string $purge_cfs=null null=dont, 'ical'=only iCal X-properties (cfs name starting with "#"), 'all'=all cfs
|
||||
* @param boolean $check_defaults = true check and set certain defaults
|
||||
* @param boolean|int $touch_modified = true touch the modification date and sets the modifier's user-id, 2: only modifier
|
||||
* @param boolean $user2server = true conversion between user- and server-time necessary
|
||||
* @param boolean $skip_notification = false true = do NOT send notification, false (default) = send notifications
|
||||
* @param boolean $throw_exception = false Throw an exception (if required fields are not set)
|
||||
* @param string $purge_cfs = null null=dont, 'ical'=only iCal X-properties (cfs name starting with "#"), 'all'=all cfs
|
||||
*
|
||||
* @return int|boolean info_id on a successfull write or false
|
||||
*/
|
||||
@ -1102,7 +1102,7 @@ class infolog_bo
|
||||
/**
|
||||
* Query ctag for infolog
|
||||
*
|
||||
* @param array $filter=array('filter'=>'own','info_type'=>'task')
|
||||
* @param array $filter = array('filter'=>'own','info_type'=>'task')
|
||||
* @return string
|
||||
*/
|
||||
public function getctag(array $filter=array('filter'=>'own','info_type'=>'task'))
|
||||
@ -1131,33 +1131,29 @@ class infolog_bo
|
||||
*
|
||||
* @author Cornelius Weiss <nelius@cwtech.de>
|
||||
* @todo search if infolog with from and subject allready exists ->appned body & inform user
|
||||
* @param string $_email_address rfc822 conform emailaddresses
|
||||
* @param array $_addresses array of addresses
|
||||
* - array (email,name)
|
||||
* @param string $_subject
|
||||
* @param string $_message
|
||||
* @param array $_attachments
|
||||
* @param string $_date
|
||||
* @return array $content array for uiinfolog
|
||||
*/
|
||||
function import_mail($_email_address,$_subject,$_message,$_attachments,$_date)
|
||||
function import_mail($_addresses,$_subject,$_message,$_attachments,$_date)
|
||||
{
|
||||
$address_array = imap_rfc822_parse_adrlist($_email_address,'');
|
||||
foreach ((array)$address_array as $address)
|
||||
foreach($_addresses as $address)
|
||||
{
|
||||
$email[] = $emailadr = sprintf('%s@%s',
|
||||
trim($address->mailbox),
|
||||
trim($address->host));
|
||||
$name[] = !empty($address->personal) ? $address->personal : $emailadr;
|
||||
$names[] = $address['name'];
|
||||
$emails[] =$address['email'];
|
||||
}
|
||||
// shorten long (> $this->max_line_chars) lines of "line" chars (-_+=~) in mails
|
||||
$_message = preg_replace_callback('/[-_+=~\.]{'.$this->max_line_chars.',}/m',
|
||||
create_function('$matches',"return substr(\$matches[0],0,$this->max_line_chars);"),$_message);
|
||||
|
||||
$type = isset($this->enums['type']['email']) ? 'email' : 'note';
|
||||
$status = isset($this->status['defaults'][$type]) ? $this->status['defaults'][$type] : 'done';
|
||||
$info = array(
|
||||
'info_id' => 0,
|
||||
'info_type' => $type,
|
||||
'info_from' => implode(', ',$name),
|
||||
'info_addr' => implode(', ',$email),
|
||||
'info_from' => implode(', ',$names),
|
||||
'info_addr' => implode(', ',$emails),
|
||||
'info_subject' => $_subject,
|
||||
'info_des' => $_message,
|
||||
'info_startdate' => egw_time::server2user($_date),
|
||||
@ -1174,7 +1170,7 @@ class infolog_bo
|
||||
// find the addressbookentry to link with
|
||||
$addressbook = new addressbook_bo();
|
||||
$contacts = array();
|
||||
foreach ($email as $mailadr)
|
||||
foreach ($emails as $mailadr)
|
||||
{
|
||||
$contacts = array_merge($contacts,(array)$addressbook->search(
|
||||
array(
|
||||
@ -1202,14 +1198,13 @@ class infolog_bo
|
||||
{
|
||||
foreach ($_attachments as $attachment)
|
||||
{
|
||||
$is_vfs = false;
|
||||
if (parse_url($attachment['tmp_name'],PHP_URL_SCHEME) == 'vfs' && egw_vfs::is_readable($attachment['tmp_name']))
|
||||
if($attachment['egw_data'])
|
||||
{
|
||||
$is_vfs = true;
|
||||
egw_link::link('infolog',$info['link_to']['to_id'],egw_link::DATA_APPNAME, $attachment);
|
||||
}
|
||||
if(is_readable($attachment['tmp_name']) || $is_vfs)
|
||||
else if(is_readable($attachment['tmp_name']))
|
||||
{
|
||||
egw_link::link('infolog',$info['link_to']['to_id'],'file',$attachment);
|
||||
egw_link::link('infolog',$info['link_to']['to_id'],'file', $attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1294,8 +1289,8 @@ class infolog_bo
|
||||
*
|
||||
* @param int|array $id id of entry or entry array
|
||||
* @param int $check EGW_ACL_READ for read and EGW_ACL_EDIT for write or delete access
|
||||
* @param string $rel_path=null currently not used in InfoLog
|
||||
* @param int $user=null for which user to check, default current user
|
||||
* @param string $rel_path = null currently not used in InfoLog
|
||||
* @param int $user = null for which user to check, default current user
|
||||
* @return boolean true if access is granted or false otherwise
|
||||
*/
|
||||
function file_access($id,$check,$rel_path=null,$user=null)
|
||||
@ -1439,7 +1434,7 @@ class infolog_bo
|
||||
* currently used for ical/sif import
|
||||
*
|
||||
* @param array $catname_list names of the categories which should be found or added
|
||||
* @param int $info_id=-1 match against existing infolog and expand the returned category ids
|
||||
* @param int $info_id = -1 match against existing infolog and expand the returned category ids
|
||||
* by the ones the user normally does not see due to category permissions - used to preserve categories
|
||||
* @return array category ids (found, added and preserved categories)
|
||||
*/
|
||||
@ -1692,8 +1687,8 @@ class infolog_bo
|
||||
*
|
||||
* As status value can have different translations depending on type, we list all translations
|
||||
*
|
||||
* @param string $type=null
|
||||
* @param array &$icons=null on return name of icons
|
||||
* @param string $type = null
|
||||
* @param array &$icons = null on return name of icons
|
||||
* @return array value => (commaseparated) translations
|
||||
*/
|
||||
function get_status($type=null, array &$icons=null)
|
||||
@ -1763,8 +1758,8 @@ class infolog_bo
|
||||
* This expects timestamps to be in server-time.
|
||||
*
|
||||
* @param array $infoData the infolog data we try to find
|
||||
* @param boolean $relax=false if asked to relax, we only match against some key fields
|
||||
* @param string $tzid=null timezone, null => user time
|
||||
* @param boolean $relax = false if asked to relax, we only match against some key fields
|
||||
* @param string $tzid = null timezone, null => user time
|
||||
*
|
||||
* @return array of infolog_ids of matching entries
|
||||
*/
|
||||
|
@ -558,4 +558,17 @@ class infolog_hooks
|
||||
unset($location); // not used, but part of hook signature
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mail integration hook to import mail message contents into an infolog entry
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function mail_import($args)
|
||||
{
|
||||
return array (
|
||||
'menuaction' => 'infolog.infolog_ui.mail_import',
|
||||
'popup' => egw_link::get_registry('infolog', 'edit_popup')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class infolog_ui
|
||||
'admin' => True,
|
||||
'hook_view' => True,
|
||||
'writeLangFile' => True,
|
||||
'import_mail' => True,
|
||||
'mail_import' => True
|
||||
);
|
||||
/**
|
||||
* reference to the infolog preferences of the user
|
||||
@ -2482,185 +2482,25 @@ class infolog_ui
|
||||
|
||||
/**
|
||||
* imports a mail as infolog
|
||||
* two possible calls:
|
||||
* 1. with function args set. (we come from send mail)
|
||||
* 2. with $_GET['uid] = someuid (we come from display mail)
|
||||
*
|
||||
* @author Cornelius Weiss <nelius@cwtech.de>
|
||||
* @param string $_to_emailAddress
|
||||
* @param string $_subject
|
||||
* @param string $_body
|
||||
* @param array $_attachments
|
||||
* @param string $_date
|
||||
* @param resource $_rawMail
|
||||
* @param array $mailContent = null content of mail
|
||||
* @return array
|
||||
*/
|
||||
function import_mail($_to_emailAddress=false,$_subject=false,$_body=false,$_attachments=false,$_date=false,$_rawMail=null)
|
||||
function mail_import(array $mailContent=null)
|
||||
{
|
||||
$uid = $_GET['uid'];
|
||||
$partid = $_GET['part'];
|
||||
$mailbox = base64_decode($_GET['mailbox']);
|
||||
$mailClass = 'mail_bo';
|
||||
$sessionLocation = 'mail';
|
||||
// if rowid is set, we are called from new mail module.
|
||||
if (method_exists('mail_ui','splitRowID') && isset($_GET['rowid']) && !empty($_GET['rowid']))
|
||||
// It would get called from compose as a popup with egw_data
|
||||
if (!is_array($mailContent) && ($_GET['egw_data']))
|
||||
{
|
||||
// rowid holds all needed information: server, folder, uid, etc.
|
||||
$rowID = $_GET['rowid'];
|
||||
$hA = mail_ui::splitRowID($rowID);
|
||||
$sessionLocation = $hA['app']; // THIS is part of the row ID, we may use this for validation
|
||||
if ($sessionLocation != 'mail') throw new egw_exception_assertion_failed(lang('Application mail expected but got: %1',$sessionLocation));
|
||||
$uid = $hA['msgUID'];
|
||||
$mailbox = $hA['folder'];
|
||||
$icServerID = $hA['profileID'];
|
||||
$mailClass = 'mail_bo';
|
||||
// get the mail raw data
|
||||
egw_link::get_data ($_GET['egw_data']);
|
||||
return false;
|
||||
}
|
||||
if ($_date == false || empty($_date)) $_date = $this->bo->user_time_now;
|
||||
if (!empty($_to_emailAddress))
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = 'infolog';
|
||||
|
||||
if (!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')&&is_array($_attachments))
|
||||
{
|
||||
//echo __METHOD__.'<br>';
|
||||
//_debug_array($_attachments);
|
||||
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
|
||||
$mailobject = $mailClass::getInstance(true,$icServerID);
|
||||
$mailobject->openConnection();
|
||||
foreach ($_attachments as $attachment)
|
||||
{
|
||||
//error_log(__METHOD__.__LINE__.array2string($attachment));
|
||||
if (trim(strtoupper($attachment['type'])) == 'MESSAGE/RFC822' && !empty($attachment['uid']) && !empty($attachment['folder']))
|
||||
{
|
||||
$mailobject->reopen(($attachment['folder']?$attachment['folder']:$mailbox));
|
||||
|
||||
// get the message itself, and attach it, as we are able to display it in egw
|
||||
// instead of fetching only the attachments attached files (as we did previously)
|
||||
$message = $mailobject->getMessageRawBody($attachment['uid'],$attachment['partID'],($attachment['folder']?$attachment['folder']:$mailbox));
|
||||
$headers = $mailobject->getMessageHeader($attachment['uid'],$attachment['partID'],true,false,($attachment['folder']?$attachment['folder']:$mailbox));
|
||||
$subject = $mailClass::adaptSubjectForImport($headers['SUBJECT']);
|
||||
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
|
||||
$tmpfile = fopen($attachment_file,'w');
|
||||
fwrite($tmpfile,$message);
|
||||
fclose($tmpfile);
|
||||
$size = filesize($attachment_file);
|
||||
$attachments[] = array(
|
||||
'name' => trim($subject).'.eml',
|
||||
'mimeType' => 'message/rfc822',
|
||||
'type' => 'message/rfc822',
|
||||
'tmp_name' => $attachment_file,
|
||||
'size' => $size,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($attachment['folder']))
|
||||
{
|
||||
$is_winmail = $_GET['is_winmail'] ? $_GET['is_winmail'] : 0;
|
||||
$mailobject->reopen($attachment['folder']);
|
||||
$attachmentData = $mailobject->getAttachment($attachment['uid'],$attachment['partID'],$is_winmail);
|
||||
$attachment['file'] =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
|
||||
$tmpfile = fopen($attachment['file'],'w');
|
||||
fwrite($tmpfile,$attachmentData['attachment']);
|
||||
fclose($tmpfile);
|
||||
}
|
||||
//make sure we search for our attached file in our configured temp_dir
|
||||
if (isset($attachment['file']) && parse_url($attachment['file'],PHP_URL_SCHEME) != 'vfs' &&
|
||||
file_exists($GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file'])))
|
||||
{
|
||||
$attachment['file'] = $GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file']);
|
||||
}
|
||||
$attachments[] = array(
|
||||
'name' => $attachment['name'],
|
||||
'mimeType' => $attachment['type'],
|
||||
'type' => $attachment['type'],
|
||||
'tmp_name' => $attachment['file'],
|
||||
'size' => $attachment['size'],
|
||||
);
|
||||
}
|
||||
}
|
||||
$mailobject->closeConnection();
|
||||
}
|
||||
// this one adds the mail itself (as message/rfc822 (.eml) file) to the infolog as additional attachment
|
||||
// this is done to have a simple archive functionality (ToDo: opening .eml in email module)
|
||||
if (is_resource($_rawMail) && $GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw')
|
||||
{
|
||||
$subject = $mailClass::adaptSubjectForImport($_subject);
|
||||
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
|
||||
$tmpfile = fopen($attachment_file,'w');
|
||||
fseek($_rawMail, 0, SEEK_SET);
|
||||
stream_copy_to_stream($_rawMail, $tmpfile);
|
||||
fclose($tmpfile);
|
||||
$size = filesize($attachment_file);
|
||||
$attachments[] = array(
|
||||
'name' => trim($subject).'.eml',
|
||||
'mimeType' => 'message/rfc822',
|
||||
'type' => 'message/rfc822',
|
||||
'tmp_name' => $attachment_file,
|
||||
'size' => $size,
|
||||
);
|
||||
}
|
||||
|
||||
//_debug_array($_to_emailAddress);
|
||||
$toaddr = array();
|
||||
foreach(array('to','cc','bcc') as $x)
|
||||
{
|
||||
if (is_array($_to_emailAddress[$x]) && !empty($_to_emailAddress[$x]))
|
||||
{
|
||||
$toaddr = array_merge($toaddr,$_to_emailAddress[$x]);
|
||||
}
|
||||
}
|
||||
//_debug_array($attachments);
|
||||
$body_striped = strip_tags($_body); //we need to fix broken tags (or just stuff like "<800 USD/p" )
|
||||
$body_decoded = htmlspecialchars_decode($body_striped,ENT_QUOTES);
|
||||
$body = $mailClass::createHeaderInfoSection(array('FROM'=>$_to_emailAddress['from'],
|
||||
'TO'=>(!empty($_to_emailAddress['to'])?implode(',',$_to_emailAddress['to']):null),
|
||||
'CC'=>(!empty($_to_emailAddress['cc'])?implode(',',$_to_emailAddress['cc']):null),
|
||||
'BCC'=>(!empty($_to_emailAddress['bcc'])?implode(',',$_to_emailAddress['bcc']):null),
|
||||
'SUBJECT'=>$_subject,
|
||||
'DATE'=>$mailClass::_strtotime($_date))).$body_decoded;
|
||||
$this->edit($this->bo->import_mail(
|
||||
implode(',',$toaddr),$_subject,$body,$attachments,$_date
|
||||
));
|
||||
exit;
|
||||
}
|
||||
elseif ($uid && $mailbox)
|
||||
{
|
||||
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
|
||||
$mailobject = $mailClass::getInstance(true,$icServerID);
|
||||
$mailobject->openConnection();
|
||||
$mailobject->reopen($mailbox);
|
||||
|
||||
$mailcontent = $mailClass::get_mailcontent($mailobject,$uid,$partid,$mailbox,false,true,(!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')));
|
||||
// this one adds the mail itself (as message/rfc822 (.eml) file) to the infolog as additional attachment
|
||||
// this is done to have a simple archive functionality (ToDo: opening .eml in email module)
|
||||
if ($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw')
|
||||
{
|
||||
$message = $mailobject->getMessageRawBody($uid, $partid,$mailbox);
|
||||
$headers = $mailobject->getMessageHeader($uid, $partid,true,false,$mailbox);
|
||||
$subject = $mailClass::adaptSubjectForImport($headers['SUBJECT']);
|
||||
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
|
||||
$tmpfile = fopen($attachment_file,'w');
|
||||
fwrite($tmpfile,$message);
|
||||
fclose($tmpfile);
|
||||
$size = filesize($attachment_file);
|
||||
$mailcontent['attachments'][] = array(
|
||||
'name' => trim($subject).'.eml',
|
||||
'mimeType' => 'message/rfc822',
|
||||
'type' => 'message/rfc822',
|
||||
'tmp_name' => $attachment_file,
|
||||
'size' => $size,
|
||||
);
|
||||
}
|
||||
//_debug_array($mailcontent);
|
||||
return $this->edit($this->bo->import_mail(
|
||||
$mailcontent['mailaddress'],
|
||||
$mailcontent['subject'],
|
||||
$mailcontent['message'],
|
||||
$mailcontent['attachments'],
|
||||
strtotime($mailcontent['headers']['DATE'])
|
||||
));
|
||||
}
|
||||
egw_framework::window_close(lang('Error: no mail (Mailbox / UID) given!'));
|
||||
|
||||
return $this->edit($this->bo->import_mail($mailContent['addresses'],
|
||||
$mailContent['subject'],
|
||||
$mailContent['message'],
|
||||
$mailContent['attachments'],
|
||||
$mailContent['date']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,6 +63,7 @@ $setup_info['infolog']['hooks']['search_link'] = 'infolog_hooks::search_link';
|
||||
$setup_info['infolog']['hooks']['pm_custom_app_icons'] = 'infolog.infolog_bo.pm_icons';
|
||||
$setup_info['infolog']['hooks']['timesheet_set'] = 'infolog.infolog_ui.timesheet_set';
|
||||
$setup_info['infolog']['hooks']['calendar_set'] = 'infolog.infolog_ui.calendar_set';
|
||||
$setup_info['infolog']['hooks']['mail_import'] = 'infolog_hooks::mail_import';
|
||||
|
||||
/* Dependencies for this app to work */
|
||||
$setup_info['infolog']['depends'][] = array(
|
||||
|
@ -163,6 +163,14 @@ class mail_compose
|
||||
'hint' => 'check to save as trackerentry on send',
|
||||
'onExecute' => 'javaScript:app.mail.compose_setToggle'
|
||||
),
|
||||
'to_calendar' => array(
|
||||
'caption' => 'Calendar',
|
||||
'icon' => 'to_calendar',
|
||||
'group' => $group,
|
||||
'checkbox' => true,
|
||||
'hint' => 'check to save as calendar event on send',
|
||||
'onExecute' => 'javaScript:app.mail.compose_setToggle'
|
||||
),
|
||||
'disposition' => array(
|
||||
'caption' => 'Notification',
|
||||
'icon' => 'high',
|
||||
@ -1002,14 +1010,11 @@ class mail_compose
|
||||
}
|
||||
}
|
||||
}
|
||||
//Since the ckeditor is not stable enough on mobile devices, we always convert html messages to plain text
|
||||
//TODO: needs to remove html:$ua_mobile condition after better mobile support from CKeditor
|
||||
//mobile compatibility is disabled expilcitly in ckeditor.js plugin too, which needs to be removed
|
||||
if ($content['mimeType'] == 'html' && html::htmlarea_availible()===false || html::$ua_mobile)
|
||||
|
||||
if ($content['mimeType'] == 'html' && html::htmlarea_availible()===false)
|
||||
{
|
||||
$_content['mimeType'] = $content['mimeType'] = 'plain';
|
||||
$content['body'] = $this->convertHTMLToText($content['body']);
|
||||
$readonlys['mimeType'] = true;
|
||||
}
|
||||
// is a certain signature requested?
|
||||
// only the following values are supported (and make sense)
|
||||
@ -1290,7 +1295,7 @@ class mail_compose
|
||||
|
||||
$content['to'] = self::resolveEmailAddressList($content['to']);
|
||||
//error_log(__METHOD__.__LINE__.array2string($content));
|
||||
$etpl->exec('mail.mail_compose.compose',$content,$sel_options,$readonlys,$preserv,2);
|
||||
$etpl->exec('mail.mail_compose.compose',$content,$sel_options,array(),$preserv,2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2448,7 +2453,7 @@ class mail_compose
|
||||
*/
|
||||
public function ajax_saveAsDraft ($content, $action='button[saveAsDraft]')
|
||||
{
|
||||
//error_log(__METHOD__."(, action=$action)");
|
||||
//error_log(__METHOD__.__LINE__.array2string($content)."(, action=$action)");
|
||||
$response = egw_json_response::get();
|
||||
$success = true;
|
||||
|
||||
@ -3047,43 +3052,44 @@ class mail_compose
|
||||
if (is_array($this->sessionData['cc'])) $mailaddresses['cc'] = $this->sessionData['cc'];
|
||||
if (is_array($this->sessionData['bcc'])) $mailaddresses['bcc'] = $this->sessionData['bcc'];
|
||||
if (!empty($mailaddresses)) $mailaddresses['from'] = $GLOBALS['egw']->translation->decodeMailHeader($fromAddress);
|
||||
// attention: we dont return from infolog/tracker. You cannot check both. cleanups will be done there.
|
||||
if ($_formData['to_infolog'] == 'on') {
|
||||
$uiinfolog = new infolog_ui();
|
||||
$uiinfolog->import_mail(
|
||||
$mailaddresses,
|
||||
$this->sessionData['subject'],
|
||||
$this->convertHTMLToText($this->sessionData['body']),
|
||||
$this->sessionData['attachments'],
|
||||
false, // date
|
||||
$mail->getRaw()
|
||||
);
|
||||
}
|
||||
if ($_formData['to_tracker'] == 'on') {
|
||||
$uitracker = new tracker_ui();
|
||||
$uitracker->import_mail(
|
||||
$mailaddresses,
|
||||
$this->sessionData['subject'],
|
||||
$this->convertHTMLToText($this->sessionData['body']),
|
||||
$this->sessionData['attachments'],
|
||||
false, // date
|
||||
$mail->getRaw()
|
||||
);
|
||||
}
|
||||
/*
|
||||
if ($_formData['to_calendar'] == 'on') {
|
||||
$uical =& CreateObject('calendar.calendar_uiforms');
|
||||
$uical->import_mail(
|
||||
$mailaddresses,
|
||||
$this->sessionData['subject'],
|
||||
$this->convertHTMLToText($this->sessionData['body']),
|
||||
$this->sessionData['attachments']
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
if ($_formData['to_infolog'] == 'on' || $_formData['to_tracker'] == 'on' || $_formData['to_calendar'] == 'on' )
|
||||
{
|
||||
foreach(array('to_infolog','to_tracker','to_calendar') as $app_key)
|
||||
{
|
||||
if ($_formData[$app_key] == 'on')
|
||||
{
|
||||
$app_name = substr($app_key,3);
|
||||
// Get registered hook data of the app called for integration
|
||||
$hook = $GLOBALS['egw']->hooks->single(array('location'=> 'mail_import'),$app_name);
|
||||
|
||||
if(is_array($this->sessionData['attachments'])) {
|
||||
// store mail / eml in temp. file to not have to download it from mail-server again
|
||||
$eml = tempnam($GLOBALS['egw_info']['server']['temp_dir'],'mail_integrate');
|
||||
$eml_fp = fopen($eml, 'w');
|
||||
stream_copy_to_stream($mail->getRaw(), $eml_fp);
|
||||
fclose($eml_fp);
|
||||
|
||||
// Open the app called for integration in a popup
|
||||
// and store the mail raw data as egw_data, in order to
|
||||
// be stored from registered app method later
|
||||
egw_framework::popup(egw::link('/index.php', array(
|
||||
'menuaction' => $hook['menuaction'],
|
||||
'egw_data' => egw_link::set_data(null,'mail_integration::integrate',array(
|
||||
$mailaddresses,
|
||||
$this->sessionData['subject'],
|
||||
$this->convertHTMLToText($this->sessionData['body']),
|
||||
$this->sessionData['attachments'],
|
||||
false, // date
|
||||
$eml,
|
||||
$_formData['serverID']),true),
|
||||
'app' => $app_name
|
||||
)),'_blank',$hook['popup']);
|
||||
}
|
||||
}
|
||||
}
|
||||
// only clean up temp-files, if we dont need them for mail_integration::integrate
|
||||
elseif(is_array($this->sessionData['attachments']))
|
||||
{
|
||||
foreach($this->sessionData['attachments'] as $value) {
|
||||
if (!empty($value['file']) && parse_url($value['file'],PHP_URL_SCHEME) != 'vfs') { // happens when forwarding mails
|
||||
unlink($GLOBALS['egw_info']['server']['temp_dir'].'/'.$value['file']);
|
||||
@ -3302,6 +3308,22 @@ class mail_compose
|
||||
}
|
||||
}
|
||||
|
||||
// Add groups
|
||||
$group_options = array('account_type' => 'groups');
|
||||
$groups = $GLOBALS['egw']->accounts->link_query($_searchString, $group_options);
|
||||
foreach($groups as $g_id => $name)
|
||||
{
|
||||
$group = $GLOBALS['egw']->accounts->read($g_id);
|
||||
if(!$group['account_email']) continue;
|
||||
$completeMailString = trim($name) .' <'. trim($group['account_email']) .'>';
|
||||
$results[] = array(
|
||||
'id' => $completeMailString,
|
||||
'label' => $completeMailString,
|
||||
'name' => $name,
|
||||
'title' => $group['account_email']
|
||||
);
|
||||
}
|
||||
|
||||
// Add up to 5 matching mailing lists
|
||||
if($include_lists)
|
||||
{
|
||||
|
288
mail/inc/class.mail_integration.inc.php
Normal file
288
mail/inc/class.mail_integration.inc.php
Normal file
@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware - Mail - integration interface class
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @package mail
|
||||
* @author Hadi Nategh [hn@stylite.de]
|
||||
* @copyright (c) 2015 by Stylite AG <info-AT-stylite.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id:$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class cotains methods and functions
|
||||
* to be used to integrate mail's message into other applications
|
||||
*
|
||||
*/
|
||||
class mail_integration {
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
* @var type
|
||||
*/
|
||||
var $public_functions = array(
|
||||
'integrate' => true
|
||||
);
|
||||
|
||||
/**
|
||||
* Maximum number of line characters (-_+=~) allowed in a mail, to not stall the layout.
|
||||
* Longer lines / biger number of these chars are truncated to that max. number or chars.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MAX_LINE_CHARS = 40;
|
||||
|
||||
/**
|
||||
* Gets requested mail information and sets them as data link
|
||||
* -Execute registered hook method from the requested app for integration
|
||||
* -with provided content from mail:
|
||||
*
|
||||
* -array( 'addresses' => array (
|
||||
* 'email'=> stirng,
|
||||
* 'personel' => string),
|
||||
* 'attachments' => array (
|
||||
* 'name' => string, // file name
|
||||
* 'type' => string, // mime type
|
||||
* 'egw_data'=> string, // hash md5 id of an stored attachment in session (attachment which is in IMAP server)
|
||||
* // NOTE: the attachmet either have egw_data OR tmp_name (e.g. raw mail eml file stores in tmp)
|
||||
* 'tmp_name' => string), // tmp dir path
|
||||
* 'message' => string,
|
||||
* 'date' => string,
|
||||
* 'subject' => string,
|
||||
* 'entry_id => string // Id of the app entry which mail content will append to
|
||||
* )
|
||||
*
|
||||
* @param string $_to_emailAddress
|
||||
* @param string $_subject mail subject
|
||||
* @param string $_body mail message
|
||||
* @param array $_attachments attachments
|
||||
* @param string $_date
|
||||
* @param string $_rawMail path to file with raw mail
|
||||
* @param int $_icServerID mail profile id
|
||||
* @throws egw_exception_assertion_failed
|
||||
*/
|
||||
public static function integrate ($_to_emailAddress=false,$_subject=false,$_body=false,$_attachments=false,$_date=false,$_rawMail=null,$_icServerID=null)
|
||||
{
|
||||
// App name which is called for integration
|
||||
$app = isset($GLOBALS['egw_info']['user']['apps'][$_GET['app']])? $_GET['app'] : null;
|
||||
|
||||
// preset app entry id, selected by user from app_entry_dialog
|
||||
$app_entry_id = $_GET['entry_id'];
|
||||
|
||||
// Set the date
|
||||
if (!$_date)
|
||||
{
|
||||
$time = time();
|
||||
$_date = egw_time::server2user($time->now,'ts');
|
||||
}
|
||||
|
||||
// Integrate not yet saved mail
|
||||
if (empty($_GET['rowid']) && $_to_emailAddress && $app)
|
||||
{
|
||||
$sessionLocation = 'mail';
|
||||
$mailbox = base64_decode($_GET['mailbox']);
|
||||
|
||||
$GLOBALS['egw_info']['flags']['currentapp'] = $app;
|
||||
|
||||
if (!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')&&is_array($_attachments))
|
||||
{
|
||||
// initialize mail open connection requirements
|
||||
if (!isset($_icServerID)) $_icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
|
||||
$mo = mail_bo::getInstance(true,$_icServerID);
|
||||
$mo->openConnection();
|
||||
|
||||
foreach ($_attachments as $attachment)
|
||||
{
|
||||
if (trim(strtoupper($attachment['type'])) == 'MESSAGE/RFC822' && !empty($attachment['uid']) && !empty($attachment['folder']))
|
||||
{
|
||||
$mo->reopen(($attachment['folder']?$attachment['folder']:$mailbox));
|
||||
|
||||
// get the message itself, and attach it, as we are able to display it in egw
|
||||
// instead of fetching only the attachments attached files (as we did previously)
|
||||
$message = $mo->getMessageRawBody($attachment['uid'],$attachment['partID'],($attachment['folder']?$attachment['folder']:$mailbox));
|
||||
$headers = $mo->getMessageHeader($attachment['uid'],$attachment['partID'],true,false,($attachment['folder']?$attachment['folder']:$mailbox));
|
||||
$subject = mail_bo::adaptSubjectForImport($headers['SUBJECT']);
|
||||
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
|
||||
$tmpfile = fopen($attachment_file,'w');
|
||||
fwrite($tmpfile,$message);
|
||||
fclose($tmpfile);
|
||||
$size = filesize($attachment_file);
|
||||
$attachments[] = array(
|
||||
'name' => trim($subject).'.eml',
|
||||
'mimeType' => 'message/rfc822',
|
||||
'type' => 'message/rfc822',
|
||||
'tmp_name' => $attachment_file,
|
||||
'size' => $size,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!empty($attachment['folder']))
|
||||
{
|
||||
$is_winmail = $_GET['is_winmail'] ? $_GET['is_winmail'] : 0;
|
||||
$mo->reopen($attachment['folder']);
|
||||
$attachmentData = $mo->getAttachment($attachment['uid'],$attachment['partID'],$is_winmail);
|
||||
$attachment['file'] =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
|
||||
$tmpfile = fopen($attachment['file'],'w');
|
||||
fwrite($tmpfile,$attachmentData['attachment']);
|
||||
fclose($tmpfile);
|
||||
}
|
||||
//make sure we search for our attached file in our configured temp_dir
|
||||
if (isset($attachment['file']) && parse_url($attachment['file'],PHP_URL_SCHEME) != 'vfs' &&
|
||||
file_exists($GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file'])))
|
||||
{
|
||||
$attachment['file'] = $GLOBALS['egw_info']['server']['temp_dir'].SEP.basename($attachment['file']);
|
||||
}
|
||||
$attachments[] = array(
|
||||
'name' => $attachment['name'],
|
||||
'mimeType' => $attachment['type'],
|
||||
'type' => $attachment['type'],
|
||||
'tmp_name' => $attachment['file'],
|
||||
'size' => $attachment['size'],
|
||||
);
|
||||
}
|
||||
}
|
||||
$mo->closeConnection();
|
||||
}
|
||||
// this one adds the mail itself (as message/rfc822 (.eml) file) to the app as additional attachment
|
||||
// this is done to have a simple archive functionality (ToDo: opening .eml in email module)
|
||||
if ($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw' &&
|
||||
$_rawMail && file_exists($_rawMail))
|
||||
{
|
||||
$subject = mail_bo::adaptSubjectForImport($_subject);
|
||||
$attachments[] = array(
|
||||
'name' => trim($subject).'.eml',
|
||||
'mimeType' => 'message/rfc822',
|
||||
'type' => 'message/rfc822',
|
||||
'tmp_name' => $_rawMail,
|
||||
'size' => filesize($_rawMail),
|
||||
'add_raw' => true
|
||||
);
|
||||
}
|
||||
|
||||
$toaddr = array();
|
||||
foreach(array('to','cc','bcc') as $x)
|
||||
{
|
||||
if (is_array($_to_emailAddress[$x]) && !empty($_to_emailAddress[$x]))
|
||||
{
|
||||
$toaddr = array_merge($toaddr,$_to_emailAddress[$x]);
|
||||
}
|
||||
}
|
||||
$body_striped = strip_tags($_body); //we need to fix broken tags (or just stuff like "<800 USD/p" )
|
||||
$body_decoded = htmlspecialchars_decode($body_striped,ENT_QUOTES);
|
||||
$body = mail_bo::createHeaderInfoSection(array('FROM'=>$_to_emailAddress['from'],
|
||||
'TO'=>(!empty($_to_emailAddress['to'])?implode(',',$_to_emailAddress['to']):null),
|
||||
'CC'=>(!empty($_to_emailAddress['cc'])?implode(',',$_to_emailAddress['cc']):null),
|
||||
'BCC'=>(!empty($_to_emailAddress['bcc'])?implode(',',$_to_emailAddress['bcc']):null),
|
||||
'SUBJECT'=>$_subject,
|
||||
'DATE'=>mail_bo::_strtotime($_date))).$body_decoded;
|
||||
|
||||
$mailcontent = array(
|
||||
'mailaddress' => implode(',',$toaddr),
|
||||
'subject' => $_subject,
|
||||
'message' => $body,
|
||||
'attachments' => $attachments,
|
||||
'date' => $_date
|
||||
);
|
||||
|
||||
}
|
||||
// Integrate already saved mail with ID
|
||||
else
|
||||
{
|
||||
// Initializing mail connection requirements
|
||||
$hA = mail_ui::splitRowID($_GET['rowid']);
|
||||
$sessionLocation = $hA['app']; // THIS is part of the row ID, we may use this for validation
|
||||
// Check the mail app
|
||||
if ($sessionLocation != 'mail') throw new egw_exception_assertion_failed(lang('Application mail expected but got: %1',$sessionLocation));
|
||||
$uid = $hA['msgUID'];
|
||||
$mailbox = $hA['folder'];
|
||||
$icServerID = $hA['profileID'];
|
||||
|
||||
if ($uid && $mailbox)
|
||||
{
|
||||
if (!isset($icServerID)) $icServerID =& egw_cache::getSession($sessionLocation,'activeProfileID');
|
||||
$mo = mail_bo::getInstance(true,$icServerID);
|
||||
$mo->openConnection();
|
||||
$mo->reopen($mailbox);
|
||||
$mailcontent = mail_bo::get_mailcontent($mo,$uid,'',$mailbox,false,true,(!($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='text_only')));
|
||||
// this one adds the mail itself (as message/rfc822 (.eml) file) to the app as additional attachment
|
||||
// this is done to have a simple archive functionality (ToDo: opening .eml in email module)
|
||||
if ($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw')
|
||||
{
|
||||
$message = $mo->getMessageRawBody($uid, '',$mailbox);
|
||||
$headers = $mo->getMessageHeader($uid, '',true,false,$mailbox);
|
||||
$subject = mail_bo::adaptSubjectForImport($headers['SUBJECT']);
|
||||
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."mail_integrate");
|
||||
$tmpfile = fopen($attachment_file,'w');
|
||||
fwrite($tmpfile,$message);
|
||||
fclose($tmpfile);
|
||||
$size = filesize($attachment_file);
|
||||
$mailcontent['attachments'][] = array(
|
||||
'name' => trim($subject).'.eml',
|
||||
'mimeType' => 'message/rfc822',
|
||||
'type' => 'message/rfc822',
|
||||
'tmp_name' => $attachment_file,
|
||||
'size' => $size,
|
||||
'add_raw' => true
|
||||
);
|
||||
}
|
||||
$mailcontent['date'] = strtotime($mailcontent['headers']['DATE']);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert addresses to email and personal
|
||||
$addresses = imap_rfc822_parse_adrlist($mailcontent['mailaddress'],'');
|
||||
foreach ($addresses as $address)
|
||||
{
|
||||
$email = sprintf('%s@%s',trim($address->mailbox),trim($address->host));
|
||||
$data_addresses[] = array (
|
||||
'email' => $email,
|
||||
'name' => !empty($address->personal) ? $address->personal : $email
|
||||
);
|
||||
}
|
||||
|
||||
// shorten long (> self::max_line_chars) lines of "line" chars (-_+=~) in mails
|
||||
$data_message = preg_replace_callback(
|
||||
'/[-_+=~\.]{'.self::MAX_LINE_CHARS.',}/m',
|
||||
function($matches) {
|
||||
return substr($matches[0],0,self::MAX_LINE_CHARS);
|
||||
},
|
||||
$mailcontent['message']
|
||||
);
|
||||
|
||||
// Get attachments ready for integration as link
|
||||
if (is_array($mailcontent['attachments']))
|
||||
{
|
||||
foreach($mailcontent['attachments'] as $key => $attachment)
|
||||
{
|
||||
$data_attachments[$key] = array(
|
||||
'name' => $mailcontent['attachments'][$key]['name'],
|
||||
'type' => $mailcontent['attachments'][$key]['type'],
|
||||
'size' => $mailcontent['attachments'][$key]['size'],
|
||||
'tmp_name' => $mailcontent['attachments'][$key]['tmp_name']
|
||||
);
|
||||
if ($uid && !$mailcontent['attachments'][$key]['add_raw'])
|
||||
{
|
||||
$data_attachments[$key]['egw_data'] = egw_link::set_data($mailcontent['attachments'][$key]['mimeType'],
|
||||
'emailadmin_imapbase::getAttachmentAccount',array($icServerID, $mailbox, $uid, $attachment['partID'], $is_winmail, true),true);
|
||||
}
|
||||
unset($mailcontent['attachments'][$key]['add_raw']);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the registered hook method of requested app for integration
|
||||
$hook = $GLOBALS['egw']->hooks->single(array('location' => 'mail_import'),$app);
|
||||
|
||||
// Execute import mail with provided content
|
||||
ExecMethod($hook['menuaction'],array (
|
||||
'addresses' => $data_addresses,
|
||||
'attachments' => $data_attachments,
|
||||
'message' => $data_message,
|
||||
'date' => $mailcontent['date'],
|
||||
'subject' => $mailcontent['subject'],
|
||||
'entry_id' => $app_entry_id
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -125,12 +125,12 @@ class mail_ui
|
||||
if ($_GET["resetConnection"])
|
||||
{
|
||||
unset($_GET["resetConnection"]);
|
||||
if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Connection Reset triggered:'.$connectionReset.' for Profile with ID:'.self::$icServerID);
|
||||
if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Connection Reset triggered: for Profile with ID:'.self::$icServerID);
|
||||
emailadmin_imapbase::unsetCachedObjects(self::$icServerID);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->mail_bo = mail_bo::getInstance(true,self::$icServerID,$_validate=true, $_oldImapServerObject=false, $_reuseCache=true);
|
||||
$this->mail_bo = mail_bo::getInstance(true,self::$icServerID, true, false, true);
|
||||
if (mail_bo::$debug) error_log(__METHOD__.__LINE__.' Fetched IC Server:'.self::$icServerID.'/'.$this->mail_bo->profileID.':'.function_backtrace());
|
||||
//error_log(__METHOD__.__LINE__.array2string($this->mail_bo->icServer));
|
||||
|
||||
@ -1224,8 +1224,7 @@ class mail_ui
|
||||
'hint' => 'Save as InfoLog',
|
||||
'icon' => 'infolog/navbar',
|
||||
'group' => ++$group,
|
||||
'onExecute' => 'javaScript:app.mail.mail_infolog',
|
||||
'url' => 'menuaction=infolog.infolog_ui.import_mail',
|
||||
'onExecute' => 'javaScript:app.mail.mail_integrate',
|
||||
'popup' => egw_link::get_registry('infolog', 'add_popup'),
|
||||
'allowOnMultiple' => false,
|
||||
'toolbarDefault' => true
|
||||
@ -1235,11 +1234,21 @@ class mail_ui
|
||||
'hint' => 'Save as ticket',
|
||||
'group' => $group,
|
||||
'icon' => 'tracker/navbar',
|
||||
'onExecute' => 'javaScript:app.mail.mail_tracker',
|
||||
'url' => 'menuaction=tracker.tracker_ui.import_mail',
|
||||
'onExecute' => 'javaScript:app.mail.mail_integrate',
|
||||
'popup' => egw_link::get_registry('tracker', 'add_popup'),
|
||||
'mail_import' => $GLOBALS['egw']->hooks->single(array('location' => 'mail_import'),'tracker'),
|
||||
'allowOnMultiple' => false,
|
||||
),
|
||||
'calendar' => array(
|
||||
'caption' => 'Calendar',
|
||||
'hint' => 'Save as Calendar',
|
||||
'icon' => 'calendar/navbar',
|
||||
'group' => $group,
|
||||
'onExecute' => 'javaScript:app.mail.mail_integrate',
|
||||
'popup' => egw_link::get_registry('calendar', 'add_popup'),
|
||||
'allowOnMultiple' => false,
|
||||
'toolbarDefault' => true
|
||||
),
|
||||
'print' => array(
|
||||
'caption' => 'Print',
|
||||
'group' => ++$group,
|
||||
@ -3239,7 +3248,6 @@ class mail_ui
|
||||
$file = $content['uploadForImport'];
|
||||
}
|
||||
$destination = $content['FOLDER'][0];
|
||||
$rememberServerID = $icServerID = $this->mail_bo->profileID;
|
||||
|
||||
if (stripos($destination,self::$delimiter)!==false) list($icServerID,$destination) = explode(self::$delimiter,$destination,2);
|
||||
if ($icServerID && $icServerID != $this->mail_bo->profileID)
|
||||
@ -3462,7 +3470,6 @@ class mail_ui
|
||||
$folder = $uidA['folder']; // all messages in one set are supposed to be within the same folder
|
||||
$messageID = $uidA['msgUID'];
|
||||
$icServerID = $uidA['profileID'];
|
||||
$rememberServerID = $this->mail_bo->profileID;
|
||||
if ($icServerID && $icServerID != $this->mail_bo->profileID)
|
||||
{
|
||||
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
|
||||
@ -4693,7 +4700,7 @@ class mail_ui
|
||||
//error_log(__METHOD__.__LINE__.$uID);
|
||||
if ($_copyOrMove=='move')
|
||||
{
|
||||
$messageListForRefresh[] = self::generateRowID($sourceProfileID, $folderName, $uID, $_prependApp=false);
|
||||
$messageListForRefresh[] = self::generateRowID($sourceProfileID, $_folderName, $uID, $_prependApp=false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
138
mail/js/app.js
138
mail/js/app.js
@ -2565,16 +2565,23 @@ app.classes.mail = AppJS.extend(
|
||||
},
|
||||
|
||||
/**
|
||||
* Save message as InfoLog
|
||||
* Integrate mail message into another app's entry
|
||||
*
|
||||
* @param _action
|
||||
* @param _elems _elems[0].id is the row-id
|
||||
*/
|
||||
mail_infolog: function(_action, _elems)
|
||||
mail_integrate: function(_action, _elems)
|
||||
{
|
||||
//define/preset w_h in case something fails
|
||||
var reg = '750x580';
|
||||
var w_h =reg.split('x');
|
||||
var app = _action.id;
|
||||
var w_h = ['750','580']; // define a default wxh if there's no popup size registered
|
||||
|
||||
var add_as_new = true;
|
||||
|
||||
if (typeof _action.data != 'undefined' )
|
||||
{
|
||||
if (typeof _action.data.popup != 'undefined') w_h = _action.data.popup.split('x');
|
||||
if (typeof _action.data.mail_import != 'undefined') var mail_import_hook = _action.data.mail_import;
|
||||
}
|
||||
|
||||
if (typeof _elems == 'undefined' || _elems.length==0)
|
||||
{
|
||||
@ -2591,78 +2598,73 @@ app.classes.mail = AppJS.extend(
|
||||
_elems.push({id:this.mail_currentlyFocussed});
|
||||
}
|
||||
}
|
||||
if (typeof _action.data.width == 'undefined' && typeof _action.data.height == 'undefined' && !(typeof _action.data.event == 'undefined' &&typeof _action.data.event.popup == 'undefined'))
|
||||
{
|
||||
if (_action.data.event.popup)
|
||||
{
|
||||
var app_registry = _action.data.event.popup;
|
||||
}
|
||||
else
|
||||
{
|
||||
var app_registry = egw.link_get_registry('infolog');//this.appname);
|
||||
}
|
||||
if (typeof app_registry['edit'] != 'undefined' && typeof app_registry['edit_popup'] != 'undefined' )
|
||||
{
|
||||
w_h =app_registry['edit_popup'].split('x');
|
||||
}
|
||||
}
|
||||
}
|
||||
var url = window.egw_webserverUrl+'/index.php?';
|
||||
url += 'menuaction=infolog.infolog_ui.import_mail'; // todo compose for Draft folder
|
||||
url += '&rowid='+_elems[0].id;
|
||||
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,(_action.data.width?_action.data.width:w_h[0]),(_action.data.height?_action.data.height:w_h[1]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Save message as ticket
|
||||
*
|
||||
* @param _action _action.id is 'read', 'unread', 'flagged' or 'unflagged'
|
||||
* @param _elems
|
||||
*/
|
||||
mail_tracker: function(_action, _elems)
|
||||
{
|
||||
//define/preset w_h in case something fails
|
||||
var reg = '780x535';
|
||||
var w_h =reg.split('x');
|
||||
if (typeof _elems == 'undefined' || _elems.length==0)
|
||||
|
||||
var url = window.egw_webserverUrl+ '/index.php?menuaction=mail.mail_integration.integrate&rowid=' + _elems[0].id + '&app='+app;
|
||||
|
||||
/**
|
||||
* Checks the application entry existance and offers user
|
||||
* to select desire app id to append mail content into it,
|
||||
* or add the mail content as a new app entry
|
||||
*
|
||||
* @param {string} _title select app entry title
|
||||
* @param {string} _appName app to be integrated
|
||||
* @param {string} _appCheckCallback registered mail_import hook method
|
||||
* for check app entry existance
|
||||
*/
|
||||
check_app_entry = function (_title, _appName, _appCheckCallback)
|
||||
{
|
||||
if (this.et2.getArrayMgr("content").getEntry('mail_id'))
|
||||
{
|
||||
var _elems = [];
|
||||
_elems.push({id:this.et2.getArrayMgr("content").getEntry('mail_id') || ''});
|
||||
}
|
||||
if ((typeof _elems == 'undefined' || _elems.length==0) && this.mail_isMainWindow)
|
||||
{
|
||||
if (this.mail_currentlyFocussed)
|
||||
var data = egw.dataGetUIDdata(_elems[0].id);
|
||||
var subject = (data && typeof data.data != 'undefined')? data.data.subject : '';
|
||||
egw.json(_appCheckCallback, subject,function(_entryId){
|
||||
|
||||
// if there's no entry saved already
|
||||
// open dialog in order to select one
|
||||
if (!_entryId)
|
||||
{
|
||||
var _elems = [];
|
||||
_elems.push({id:this.mail_currentlyFocussed});
|
||||
var buttons = [
|
||||
{text: 'Append', id: 'append', image: 'check', default:true},
|
||||
{text: 'Add as new', id: 'new', image: 'check'},
|
||||
{text: 'Cancel', id: 'cancel', image: 'check'}
|
||||
];
|
||||
et2_createWidget("dialog",
|
||||
{
|
||||
callback: function(_buttons, _value)
|
||||
{
|
||||
if (_buttons == 'cancel') return;
|
||||
if (_buttons == 'append' && _value)
|
||||
{
|
||||
url += '&entry_id=' + _value.id;
|
||||
}
|
||||
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
|
||||
},
|
||||
title: egw.lang(_title),
|
||||
buttons: buttons||et2_dialog.BUTTONS_OK_CANCEL,
|
||||
value:{
|
||||
content:{
|
||||
appName:_appName // appName to search on its list later
|
||||
}},
|
||||
template: egw.webserverUrl+'/mail/templates/default/integration_to_entry_dialog.xet'
|
||||
},et2_dialog._create_parent('mail'));
|
||||
}
|
||||
}
|
||||
if (typeof _action.data.width == 'undefined' && typeof _action.data.height == 'undefined' && !(typeof _action.data.event == 'undefined' &&typeof _action.data.event.popup == 'undefined'))
|
||||
{
|
||||
if (_action.data.event.popup)
|
||||
else // there is an entry saved related to this mail's subject
|
||||
{
|
||||
var app_registry = _action.data.event.popup;
|
||||
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var app_registry = egw.link_get_registry('tracker');//this.appname);
|
||||
}
|
||||
if (typeof app_registry['add'] != 'undefined' && typeof app_registry['add_popup'] != 'undefined' )
|
||||
{
|
||||
w_h =app_registry['add_popup'].split('x');
|
||||
}
|
||||
}
|
||||
},this,true,this).sendRequest();
|
||||
}
|
||||
//alert('mail_tracker('+_elems[0].id+')');
|
||||
var url = window.egw_webserverUrl+'/index.php?';
|
||||
url += 'menuaction=tracker.tracker_ui.import_mail'; // todo compose for Draft folder
|
||||
url += '&rowid='+_elems[0].id;
|
||||
egw_openWindowCentered(url,'import_tracker_'+_elems[0].id,(_action.data.width?_action.data.width:w_h[0]),(_action.data.height?_action.data.height:w_h[1]));
|
||||
|
||||
if (mail_import_hook && typeof mail_import_hook.app_entry_method != 'undefined')
|
||||
{
|
||||
check_app_entry('Select '+ app + ' entry', app, mail_import_hook.app_entry_method);
|
||||
}
|
||||
else
|
||||
{
|
||||
egw_openWindowCentered(url,'import_mail_'+_elems[0].id,w_h[0],w_h[1]);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* mail_getFormData
|
||||
*
|
||||
|
@ -373,6 +373,7 @@ saving of message %1 failed. destination folder %2 does not exist. mail de Speic
|
||||
saving of message %1 succeeded. check folder %2. mail de Speichern der Nachricht %1 war erfolgreich. Prüfen Sie den Ziel Ordner %2
|
||||
saving the rule failed: mail de Speichern der Regel ist fehlgeschlagen:
|
||||
select all mail de Alle Auswählen
|
||||
select an existing entry in order to append mail content to it mail de Bestehendes Ticket auswählen, zu dem die Mail als Kommentar hinzugefügt werden soll.
|
||||
select file to attach to message mail de Wählen Sie die Dateien aus, die Sie an diese Nachricht anhängen möchten.
|
||||
select file to import into folder mail de Wählen Sie ein E-Mail als Datei aus, damit Sie in ein Ordner importiert werden kann.
|
||||
select file(s) from vfs mail de Dateien aus dem EGroupware Dateimanager anhängen.
|
||||
|
@ -373,6 +373,7 @@ saving of message %1 failed. destination folder %2 does not exist. mail en Savin
|
||||
saving of message %1 succeeded. check folder %2. mail en Saving of message %1 succeeded. Check Folder %2.
|
||||
saving the rule failed: mail en Saving the rule failed:
|
||||
select all mail en Select all
|
||||
select an existing entry in order to append mail content to it mail en Select an existing entry in order to append mail content to it
|
||||
select file to attach to message mail en Select file to attach to message
|
||||
select file to import into folder mail en Select file to import into Folder
|
||||
select file(s) from vfs mail en Select file(s) from VFS
|
||||
|
@ -10,6 +10,7 @@
|
||||
<file class="mail-compose_fileselector" statustext="Select file to attach to message" multiple='true' progress='attachments' onFinish="app.mail.uploadForCompose" onStart="app.mail.composeUploadStart" id="uploadForCompose" drop_target ="mail-compose"/>
|
||||
<checkbox statustext="check to save as infolog on send" id="to_infolog" options="on,off"/>
|
||||
<checkbox statustext="check to save as trackerentry on send" id="to_tracker" options="on,off"/>
|
||||
<checkbox statustext="check to save as calendar event on send" id="to_calendar" options="on,off"/>
|
||||
<checkbox statustext="check to recieve a notification when the message is read (note: not all clients support this and/or the reciever may not authorize the notification)" id="disposition" options="on,off"/>
|
||||
<menulist>
|
||||
<menupopup id="priority"/>
|
||||
|
12
mail/templates/default/integration_to_entry_dialog.xet
Normal file
12
mail/templates/default/integration_to_entry_dialog.xet
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE overlay PUBLIC "-//Stylite AG//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="mail.integration_to_entry_dialog" template="" lang="" group="0" version="1.9.001">
|
||||
<vbox width="100%">
|
||||
<description value="Select an existing entry in order to append mail content to it"/>
|
||||
<description/>
|
||||
<link-entry id="id" only_app="@appName" class="et2_fullWidth"/>
|
||||
</vbox>
|
||||
</template>
|
||||
</overlay>
|
@ -112,6 +112,11 @@ class egw_link extends solink
|
||||
*/
|
||||
const VFS_APPNAME = 'file'; // pseudo-appname for own file-attachments in vfs, this is NOT the vfs-app
|
||||
|
||||
/**
|
||||
* Appname used of files stored via egw_link::set_data()
|
||||
*/
|
||||
const DATA_APPNAME = 'egw-data';
|
||||
|
||||
/**
|
||||
* appname used for linking existing files to VFS
|
||||
*/
|
||||
@ -188,9 +193,10 @@ class egw_link extends solink
|
||||
static function init_static( )
|
||||
{
|
||||
// FireFox 36 can not display pdf with it's internal viewer in an iframe used by mobile theme/template for popups
|
||||
if (html::$user_agent == 'firefox' && $GLOBALS['egw_info']['user']['preferences']['common']['theme'] == 'mobile')
|
||||
// same is true for all mobile devices
|
||||
if (html::$user_agent == 'firefox' && $GLOBALS['egw_info']['user']['preferences']['common']['theme'] == 'mobile' || html::$ua_mobile)
|
||||
{
|
||||
unset(self::$app_register['home']['mime']['application/pdf']['mime_popup']);
|
||||
unset(self::$app_register['home']['mime']['application/pdf']);
|
||||
}
|
||||
// other apps can participate in the linking by implementing a search_link hook, which
|
||||
// has to return an array in the format of an app_register entry
|
||||
@ -307,13 +313,12 @@ class egw_link extends solink
|
||||
* of not created item or $file-array if $app1 == self::VFS_APPNAME (see below).
|
||||
* If $id==0 it will be set on return to an array with the links for the new item.
|
||||
* @param string|array $app2 app of 2.linkend or array with links ($id2 not used)
|
||||
* @param string $id2 ='' id of 2. item of $file-array if $app2 == self::VFS_APPNAME (see below)<br>
|
||||
* $file array with informations about the file in format of the etemplate file-type<br>
|
||||
* $file['name'] name of the file (no directory)<br>
|
||||
* $file['type'] mine-type of the file<br>
|
||||
* $file['tmp_name'] name of the uploaded file (incl. directory)<br>
|
||||
* $file['path'] path of the file on the client computer<br>
|
||||
* $file['ip'] of the client (path and ip in $file are only needed if u want a symlink (if possible))
|
||||
* @param string $id2 ='' id of 2. item of $file-array if $app2 == self::VFS_APPNAME or self::DATA_APPNAME
|
||||
* $file array with informations about the file in format of the etemplate file-type
|
||||
* $file['name'] name of the file (no directory)
|
||||
* $file['type'] mime-type of the file
|
||||
* $file['tmp_name'] name of the uploaded file (incl. directory) for self::VFS_APPNAME or
|
||||
* $file['egw_data'] id of egw_link::set_data() call for self::DATA_APPNAME
|
||||
* @param string $remark ='' Remark to be saved with the link (defaults to '')
|
||||
* @param int $owner =0 Owner of the link (defaults to user)
|
||||
* @param int $lastmod =0 timestamp of last modification (defaults to now=time())
|
||||
@ -346,22 +351,30 @@ class egw_link extends solink
|
||||
self::link($app1, $id1, $link['app'], $link['id'], $link['remark'],$link['owner'],$link['lastmod']);
|
||||
continue;
|
||||
}
|
||||
if ($link['app'] == self::VFS_APPNAME)
|
||||
switch ($link['app'])
|
||||
{
|
||||
$link_id = self::attach_file($app1,$id1,$link['id'],$link['remark']);
|
||||
}
|
||||
else if ($link['app'] == self::VFS_LINK)
|
||||
{
|
||||
$link_id = self::link_file($app1,$id1, $link['id'],$link['remark']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$link_id = solink::link($app1,$id1,$link['app'],$link['id'],
|
||||
$link['remark'],$link['owner'],$link['lastmod']);
|
||||
case self::DATA_APPNAME:
|
||||
if (!($link['id']['tmp_name'] = self::get_data($link['id']['egw_data'], true)))
|
||||
{
|
||||
$link_id = false;
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
case self::VFS_APPNAME:
|
||||
$link_id = self::attach_file($app1,$id1,$link['id'],$link['remark']);
|
||||
break;
|
||||
|
||||
// notify both sides
|
||||
if (!($no_notify&2)) self::notify('link',$link['app'],$link['id'],$app1,$id1,$link_id);
|
||||
if (!($no_notify&1)) self::notify('link',$app1,$id1,$link['app'],$link['id'],$link_id);
|
||||
case self::VFS_LINK:
|
||||
$link_id = self::link_file($app1,$id1, $link['id'],$link['remark']);
|
||||
break;
|
||||
|
||||
default:
|
||||
$link_id = solink::link($app1,$id1,$link['app'],$link['id'],
|
||||
$link['remark'],$link['owner'],$link['lastmod']);
|
||||
// notify both sides
|
||||
if (!($no_notify&2)) self::notify('link',$link['app'],$link['id'],$app1,$id1,$link_id);
|
||||
if (!($no_notify&1)) self::notify('link',$app1,$id1,$link['app'],$link['id'],$link_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $link_id;
|
||||
@ -421,7 +434,7 @@ class egw_link extends solink
|
||||
*/
|
||||
static function temp_link_id($app,$id)
|
||||
{
|
||||
return $app.':'.($app != self::VFS_APPNAME && $app != self::VFS_LINK ? $id : $id['name']);
|
||||
return $app.':'.(!in_array($app, array(self::VFS_APPNAME,self::VFS_LINK, self::DATA_APPNAME)) ? $id : $id['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1178,9 +1191,7 @@ class egw_link extends solink
|
||||
* @param array $file informations about the file in format of the etemplate file-type
|
||||
* $file['name'] name of the file (no directory)
|
||||
* $file['type'] mine-type of the file
|
||||
* $file['tmp_name'] name of the uploaded file (incl. directory)
|
||||
* $file['path'] path of the file on the client computer
|
||||
* $file['ip'] of the client (path and ip are only needed if u want a symlink (if possible))
|
||||
* $file['tmp_name'] name of the uploaded file (incl. directory) or resource of opened file
|
||||
* @param string $comment ='' comment to add to the link
|
||||
* @return int negative id of egw_sqlfs table as negative link-id's are for vfs attachments
|
||||
*/
|
||||
@ -1552,16 +1563,18 @@ class egw_link extends solink
|
||||
* @param string $mime_type
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
* @param boolean $ignore_mime =false true: return id, even if nothing registered for given mime-type
|
||||
* @return string|null md5 hash of stored data of server-side supported mime-type or null otherwise
|
||||
*/
|
||||
public static function set_data($mime_type, $method, array $params)
|
||||
public static function set_data($mime_type, $method, array $params, $ignore_mime=false)
|
||||
{
|
||||
if (!($info = self::get_mime_info($mime_type)) || empty($info['mime_data']))
|
||||
if (!$ignore_mime && (!($info = self::get_mime_info($mime_type)) || empty($info['mime_data'])))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
array_unshift($params, $method);
|
||||
$id = md5(json_encode($params));
|
||||
$id = md5(serialize($params));
|
||||
//error_log(__METHOD__."('$mime_type', '$method', ...) params=".array2string($params)." --> json=".array2string(serialize($params)).' --> id='.array2string($id));
|
||||
egw_cache::setSession(__CLASS__, $id, $params);
|
||||
return $id;
|
||||
}
|
||||
@ -1584,6 +1597,8 @@ class egw_link extends solink
|
||||
}
|
||||
$ret = call_user_func_array('ExecMethod2', $data);
|
||||
|
||||
if (is_resource($ret)) fseek($ret, 0);
|
||||
|
||||
if ($return_resource != is_resource($ret))
|
||||
{
|
||||
if ($return_resource && ($fp = fopen('php://temp', 'w')))
|
||||
@ -1596,7 +1611,6 @@ class egw_link extends solink
|
||||
{
|
||||
$fp = $ret;
|
||||
$ret = '';
|
||||
fseek($fp, 0);
|
||||
while(!feof($fp))
|
||||
{
|
||||
$ret .= fread($fp, 8192);
|
||||
|
BIN
pixelegg/images/to_calendar.png
Normal file
BIN
pixelegg/images/to_calendar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Loading…
Reference in New Issue
Block a user